pandas变形


学习前

1、透视表

print(df.pivot(index='Math',columns='Gender',values='Height').head())       #行列中索引的值不能相同,不同则可以。
# 'Math'改为'School'则会报错。

'''
Gender      F      M
Math                
31.5      NaN  161.0
32.5    192.0    NaN
32.7      NaN  171.0
33.8    162.0    NaN
34.0      NaN  173.0
'''

由此可以看出,pivot函数具有很强的局限性,除了功能上较少之外,还不允许values中出现重复的行列索引对(pair)。换句话说,行列中索引的值不能相同,值不同才能成为索引。


2、pivot_table

%timeit df.pivot(index='ID',columns='Gender',values='Height')
%timeit pd.pivot_table(df,index='ID',columns='Gender',values='Height')

'''
2.28 ms ± 74.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
9.77 ms ± 498 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
'''

听说这个函数可以用来计算这一行代码所使用的时间,可是我运行却发现有报错,跑不起来,该怎么使用才能正常计算时间呢?


3、crosstab(交叉表)

print(pd.crosstab(index=df['Address'],columns=df['Gender']))

'''
Gender    F  M
Address       
street_1  1  2
street_2  4  2
street_4  3  5
street_5  3  3
street_6  5  1
street_7  3  3
'''

这是用于统计数量的。


print(pd.crosstab(index=df['Address'],columns=df['Gender'],
                  values=np.random.randint(1,20,df.shape[0]),aggfunc='min'))

'''
Gender     F  M
Address        
street_1   3  2
street_2   3  2
street_4  13  4
street_5  12  2
street_6   3  2
street_7   6  6
'''

里面的shape[0]的作用是什么呢?'min'是求其中的最小值的意思吗?


其他变形方法

1、melt

melt函数中的id_vars表示需要保留的列,value_vars表示需要stack的一组列

pivoted = df.pivot(index='ID',columns='Gender',values='Math')
result = pivoted.reset_index().melt(id_vars=['ID'],value_vars=['F','M'],value_name='Math')\
                     .dropna().set_index('ID').sort_index()

print(result.head())
'''
     Gender  Math
ID               
1101      M  34.0
1102      F  32.5
1103      M  87.2
1104      F  80.4
1105      F  84.8
'''

没怎么看懂


2、压缩与展开

df_s = pd.pivot_table(df,index=['Class','ID'],columns='Gender',values=['Height','Weight'])
print(df_s.groupby('Class').head(2))

df_stacked = df_s.stack()
print(df_stacked.groupby('Class').head(2))

'''
           Height        Weight      
Gender          F      M      F     M
Class ID                             
C_1   1101    NaN  173.0    NaN  63.0
      1102  192.0    NaN   73.0   NaN
C_2   1201    NaN  188.0    NaN  68.0
      1202  176.0    NaN   94.0   NaN
C_3   1301    NaN  161.0    NaN  68.0
      1302  175.0    NaN   57.0   NaN
C_4   2401  192.0    NaN   62.0   NaN
      2402    NaN  166.0    NaN  82.0

                   Height  Weight
Class ID   Gender                
C_1   1101 M        173.0    63.0
      1102 F        192.0    73.0
C_2   1201 M        188.0    68.0
      1202 F        176.0    94.0
C_3   1301 M        161.0    68.0
      1302 F        175.0    57.0
C_4   2401 F        192.0    62.0
      2402 M        166.0    82.0
'''

由上面的结果到下面的结果来看,我们可以将列索引通过stack转换成行索引。


stack函数可以看做将横向的索引放到纵向,因此功能类似与melt,参数level可指定变化的列索引是哪一层(或哪几层,需要列表)

df_stacked0 = df_s.stack(0)
df_stacked1 = df_s.stack(1)
print(df_stacked0.groupby('Class').head(2))
print(df_stacked1.groupby('Class').head(2))

'''
Gender                 F      M
Class ID                       
C_1   1101 Height    NaN  173.0
           Weight    NaN   63.0
C_2   1201 Height    NaN  188.0
           Weight    NaN   68.0
C_3   1301 Height    NaN  161.0
           Weight    NaN   68.0
C_4   2401 Height  192.0    NaN
           Weight   62.0    NaN

                   Height  Weight
Class ID   Gender                
C_1   1101 M        173.0    63.0
      1102 F        192.0    73.0
C_2   1201 M        188.0    68.0
      1202 F        176.0    94.0
C_3   1301 M        161.0    68.0
      1302 F        175.0    57.0
C_4   2401 F        192.0    62.0
      2402 M        166.0    82.0

'''

哑变量与因子化

1. Dummy Variable(哑变量)

这里主要介绍get_dummies函数,其功能主要是进行one-hot编码:

df_d = df[['Class','Gender','Weight']]
print(df_d.head())
print(pd.get_dummies(df_d[['Class','Gender']]).join(df_d['Weight']).head())

'''
  Class Gender  Weight
0   C_1      M      63
1   C_1      F      73
2   C_1      M      82
3   C_1      F      81
4   C_1      F      64
   Class_C_1  Class_C_2  Class_C_3  Class_C_4  Gender_F  Gender_M  Weight
0          1          0          0          0         0         1      63
1          1          0          0          0         1         0      73
2          1          0          0          0         0         1      82
3          1          0          0          0         1         0      81
4          1          0          0          0         1         0      64
'''

就是说,“有”则为“1”,“无”则为“0”


2. factorize方法

该方法主要用于自然数编码,并且缺失值会被记做-1,其中sort参数表示是否排序后赋值


问题与习题

问题

【问题一】 上面提到了许多变形函数,如melt/crosstab/pivot/pivot_table/stack/unstack函数,请总结它们各自的使用特点。

melt函数: 可以认为是pivot函数的逆操作,将unstacked状态的数据,压缩成stacked。

crosstab函数: 这是用于统计数量的。

pivot函数: pivot函数可将某一列作为新的cols。然而pivot函数具有很强的局限性,除了功能上较少之外,还不允许values中出现重复的行列索引对(pair)。

pivot_table函数:
①aggfunc:对组内进行聚合统计,可传入各类函数,默认为’mean’;
② margins:汇总边际状态
③ 行、列、值都可以为多级

stack函数:stack函数可以看做将横向的索引放到纵向,因此功能类似与melt,参数level可指定变化的列索引是哪一层。

unstack函数:stack的逆函数,功能上类似于pivot_table。


【问题二】 变形函数和多级索引是什么关系?哪些变形函数会使得索引维数变化?具体如何变化?

变形函数在变形后能有多级索引。例如pivot_table函数能引起维数变化。行、列、值都可以为多级。


【问题三】 请举出一个除了上文提过的关于哑变量方法的例子。

df_d = df[['School','Address','Height']]
print(df_d.head())
print(pd.get_dummies(df_d[['School','Address']]).join(df_d['Height']).head())

'''
  School   Address  Height
0    S_1  street_1     173
1    S_1  street_2     192
2    S_1  street_2     186
3    S_1  street_2     167
4    S_1  street_4     159
   School_S_1  School_S_2  ...  Address_street_7  Height
0           1           0  ...                 0     173
1           1           0  ...                 0     192
2           1           0  ...                 0     186
3           1           0  ...                 0     167
4           1           0  ...                 0     159

[5 rows x 9 columns]
'''

【问题四】 使用完stack后立即使用unstack一定能保证变化结果与原始表完全一致吗?


【问题五】 透视表中涉及了三个函数,请分别使用它们完成相同的目标(任务自定)并比较哪个速度最快。

%timeit df.pivot(index='ID',columns='Gender',values='Height')
%timeit pd.pivot_table(df,index='ID',columns='Gender',values='Height')
%timeit pd.crosstab(index=df['Address'],columns=df['Gender'])

'''
2.33 ms ± 158 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
9.76 ms ± 912 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
9.54 ms ± 792 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
'''

这波需要在控制台才能操作。


【问题六】 既然melt起到了stack的功能,为什么再设计stack函数?
stack函数中 参数level可指定变化的列索引是哪一层,功能比melt函数强大。


习题

【练习一】 继续使用上一章的药物数据集:
(a) 现在请你将数据表转化成如下形态,每行需要显示每种药物在每个地区的10年至17年的变化情况,且前三列需要排序:

df_1 = pd.pivot_table(df, index=['State', 'COUNTY', 'SubstanceName'],columns='YYYY', values='DrugReports', fill_value='-').reset_index().rename_axis(columns={'YYYY':''}).sort_index()
print(df_1.head())

'''
  State COUNTY  SubstanceName 2010 2011 2012 2013 2014 2015 2016 2017
0    KY  ADAIR  Buprenorphine    -    3    5    4   27    5    7   10
1    KY  ADAIR        Codeine    -    -    1    -    -    -    -    1
2    KY  ADAIR       Fentanyl    -    -    1    -    -    -    -    -
3    KY  ADAIR         Heroin    -    -    1    2    -    1    -    2
4    KY  ADAIR    Hydrocodone    6    9   10   10    9    7   11    3
'''

(b) 现在请将(a)中的结果恢复到原数据表,并通过equal函数检验初始表与新的结果是否一致(返回True)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值