分组级运算和转换
聚合是分组运算的其中一种。它是数据转换的一个特例,它接受能够将一维数组简化为标量值的函数。
接下来将介绍transform和apply方法,它们能够执行更多其他的分组运算。
如果要为一个DataFrame添加一个用于存放各索引分组平均值的列。一个办法是先聚合再合并
df=DataFrame({
'key1':['a','a','b','b','a'],'key2':['one','two','one','two','one'],
'data1':np.random.randn(5),'data2':np.random.randn(5)})
df
k1_means=df.groupby('key1').mean().add_prefix('mean_')
k1_means
pd.merge(df,k1_means,left_on='key1',right_index=True)
该过程看做利用np.mean函数对两个数据列进行转换,我们将在GroupBy上使用transform方法
people=DataFrame(np.random.randn(5,5),columns=['a','b','c','d','e'],
index=['Joe','Steve','Wes','Jim','Travis'])
people.loc[2:3,['b','c']]=np.nan #添加NA值
people
key=['one','two','one','two','one']
people.groupby(key).mean()
people.groupby(key).transform(np.mean)
transform会将一个函数应用到各个分组,然后将结果放置到适当的位置上。如果各分组产生的是一个标量值,则该值就会被广播出去。现在,假设你希望从各组中减去平均值。为此,我们先创建一个距平化函数(demeaning function),然后将其传给transform
def demean(arr):
return arr-arr.mean()
demeaned=people.groupby(key).transform(demean)
demeaned
检查一下demeaned现在的分组平均值是否为0
demeaned.groupby(key).mean()
apply:一般性的“拆分-应用-合并”
跟aggregate一样,transform也是一个有着严格条件的特殊函数:传入的函数只能产生两种结果,要么产生一个可以广播的标量值(如np.mean),要么产生一个相同大小的结果数组。最一般化的GroupBy方法是apply。
回到之前那个小费数据集,假设你想要根据分组选出最高的5个tip_pct值。首先,编写一个选取指定列具有最大值的行的函数
def top(df, n=