1.数据分组
pandas提供了groupby方法根据某个或几个字段对数据进行分组。
1.1 按列名分组
import numpy as np df = pd.DataFrame({'key1' : ['a', 'a', 'b', 'b', 'a'], 'key2' : ['yes', 'no', 'yes', 'yes', 'no'], 'data1' : np.random.randn(5), 'data2' : np.random.randn(5)}) print(df) groupk1 = df.groupby('key2').mean() groupk1 #------------------------------------------------- key1 key2 data1 data2 0 a yes 0.459241 0.178359 1 a no 0.707976 -0.147157 2 b yes 0.604565 -0.723689 3 b yes 1.524165 -0.332724 4 a no 1.022692 -0.303317 data1 data2 key2 no 0.865334 -0.225237 yes 0.862657 -0.292685
1.2按列表或元组分组
wlist = ['w','w','y','w','y'] df.groupby(wlist).sum() #------------------------------ data1 data2 w 2.691381 -0.301521 y 1.627258 -1.027006
1.3 按字典分组
df = pd.DataFrame(np.random.normal(size = (6,5)),index = ['a','b','c','A','B','c']) print("数据为:\n",df) wdict = {'a':'one','A':'one','b':'two','B':'two','c':'three'} print("分组汇总后的结果为:\n",df.groupby(wdict).sum()) #---------------------------------------------------------------------- 数据为: 0 1 2 3 4 a 1.083443 1.031824 0.460074 0.243467 0.036343 b 0.646914 -0.189966 -1.610353 0.323603 0.130235 c 1.847796 -0.699053 0.053289 1.274329 0.961385 A -0.966246 -0.452869 0.159198 0.500747 1.168119 B -0.066904 -1.623945 0.390718 2.085596 0.446402 c 0.048900 0.212225 1.871855 0.784043 0.508324 分组汇总后的结果为: 0 1 2 3 4 one 0.117197 0.578955 0.619272 0.744214 1.204461 three 1.896696 -0.486829 1.925144 2.058372 1.469710 two 0.580010 -1.813911 -1.219634 2.409198 0.576638
1.4按函数分组
def judge(x): if x>=0: return 'a' else: return 'b' df = pd.DataFrame(np.random.randn(4,4)) print(df) print(df[3].groupby(df[3].map(judge)).sum()) #-------------------------------------------- 0 1 2 3 0 -0.741560 -2.694231 -0.214141 -0.548934 1 0.926205 -0.164564 0.356853 0.840745 2 0.315082 -0.541750 0.256894 -0.219320 3 1.114934 -0.936713 -1.286176 -1.365191 3 a 0.840745 b -2.133445 Name: 3, dtype: float64
2.数据聚合
数据聚合就是对分组后的数据进行计算,产生标量值的数据转换过程。
2.1使用agg方法聚合函数
以下列数据为例:
不同字段统计不同数目的统计量。
data.agg({'淋巴细胞计数':np.mean,'血小板计数':[np.mean,np.std]}) #-------------------------------------------------------------- 淋巴细胞计数 血小板计数 mean 3.849164 202.765922 std NaN 58.932590
如果希望返回的结果不以分组键为索引,可以通过as_index=Flase实现。
data.groupby(['性别','是否吸烟'],as_index = False)['血小板计数'].agg(np.mean) #----------------------------------------------------------------------------- 性别 是否吸烟 血小板计数 0 女 否 212.133188 1 女 是 297.333333 2 男 否 194.236749 3 男 是 195.210175
2.2使用apply方法聚合函数
data.groupby(['性别','是否吸烟'])['血小板计数'].apply(np.mean) #------------------------------------------------------------ 性别 是否吸烟 女 否 212.133188 是 297.333333 男 否 194.236749 是 195.210175
如果希望返回的结果不以分组键为索引,同样可以设置proup_keys=False。
使用apply方法和agg方法的区别在于agg方法能够实现对不同字段应用不同的函数,而apply不行。
3.数据透视表
3.1 透视表
除了可以使用groupby方法实现以外,还可以使用pivot_table函数实现。
import pandas as pd import numpy as np data = pd.DataFrame({'k1':['a','b','a','a','c','c','b','a','c','a','b','c'],'k2':['one', 'two','three','two','one','one','three','one','two','three','one','two'], 'w':np.random.rand(12),'y':np.random.randn(12)}) print(data) print("------------------------------------------------") data.pivot_table(index = 'k1',columns = 'k2',aggfunc = 'sum') #---------------------------------------------------------------- k1 k2 w y 0 a one 0.921018 -0.973009 1 b two 0.835016 -1.895325 2 a three 0.030994 0.551870 3 a two 0.751839 -0.262889 4 c one 0.853889 -1.384951 5 c one 0.348098 0.421077 6 b three 0.723510 0.705814 7 a one 0.165716 -1.348793 8 c two 0.216771 0.685648 9 a three 0.666488 -0.468461 10 b one 0.437016 -1.906995 11 c two 0.824064 0.158887 ------------------------------------------------ w y k2 one three two one three two k1 a 1.086735 0.697482 0.751839 -2.321802 0.083409 -0.262889 b 0.437016 0.723510 0.835016 -1.906995 0.705814 -1.895325 c 1.201988 NaN 1.040835 -0.963874 NaN 0.844536
3.2 交叉表
pd.crosstab(data.k1,data.k2,margins = True) #--------------------------------------------- k2 one three two All k1 a 2 2 1 5 b 1 1 1 3 c 2 0 2 4 All 5 3 4 12
指定margin的值为True,用于在边框处增加汇总项。