groupby应用所有其他键的操作

2024-06-17 13:05:17 发布

您现在位置:Python中文网/ 问答频道 /正文

给定一个熊猫数据帧df,我可以做df.groupby('Age').apply(lambda x: x['ReadingAbility'].mean()),以获得每个年龄段的平均阅读能力。你知道吗

现在假设我想要所有年龄段的平均阅读能力,除了age=k

我能做到:

mu_other_ages = {}
for age in df['Age'].unique():
 mu_other_ages[age] = df[df['Age'] != age]['ReadingAbility'].mean()

这与groupby+apply正好相反。
有什么捷径可以更有效地达到同样的结果吗?你知道吗

请参见以下示例:

In [52]: d = pd.DataFrame([[1,10], [2,4],[1, 9], [2,3]], columns=['Age', 'ReadingAbility'])                                                                                                                        

In [53]:                                                                                                                                                                                                           

In [53]: d                                                                                                                                                                                                         
Out[53]:                                                                                                                                                                                                           
   Age  ReadingAbility                                                                                                                                                                                             
0    1              10                                                                                                                                                                                             
1    2               4                                                                                                                                                                                             
2    1               9                                                                                                                                                                                             
3    2               3                                                                                                                                                                                             

In [54]: d.groupby('Age').apply(lambda x: x['ReadingAbility'].mean())                                                                                                                                              
Out[54]:                                                                                                                                                                                                           
Age                                                                                                                                                                                                                
1    9.5                                                                                                                                                                                                           
2    3.5                                                                                                                                                                                                           
dtype: float64                                                                                                                                                                                                     

在这种情况下,只有两个不同的年龄值,其结果应该颠倒为:2=9.51=3.5,而对于更多的阶级,Age=k的值应该是:df[df['Age'] != k]['ReadingAbility'].mean()

为了澄清这个例子的预期结果是:2=9.5 and 1=3.5


Tags: lambdaindfage能力outmeanapply
3条回答
d.groupby("Age")['ReadingAbility'].mean()

得到每组的平均值。您可以通过添加一个查询来过滤,比如Age = 1

d.groupby("Age")['ReadingAbility'].mean().reset_index().query("Age != 1")

或者

d.groupby("Age")['ReadingAbility'].mean().select(lambda x: x != 1, axis=0)

或者,正如Merkle Daamgard所指出的,首先过滤掉不需要的值,然后执行groupbymean。你知道吗

d.query("Age != 1").groupby("Age")['ReadingAbility'].mean()
d.loc[d.Age != 1].groupby("Age")['ReadingAbility'].mean()
d.where(d.Age != 1).groupby("Age")['ReadingAbility'].mean()

有关详细信息,请参见^{}。你知道吗

您需要:

a = (d.groupby('Age')
      .apply(lambda x: d.loc[d['Age']!=x['Age'].iat[0], 'ReadingAbility'].mean()))

print (a)
Age
1    3.5
2    9.5
dtype: float64

另一个非常快速的解决方案是为每个组聚合sumsize,然后用两列的^{}和减去。最后划分:

np.random.seed(45)
d = pd.DataFrame(np.random.randint(10, size=(10, 2)), columns=['Age', 'ReadingAbility']) 
print (d)
   Age  ReadingAbility
0    3               0
1    5               3
2    4               9
3    8               1
4    5               9
5    6               8
6    7               8
7    5               2
8    8               1
9    6               4

a = (d.groupby('Age')
      .apply(lambda x: d.loc[d['Age']!=x['Age'].iat[0], 'ReadingAbility'].mean()))

print (a)
Age
3    5.000000
4    4.000000
5    4.428571
6    4.125000
7    4.111111
8    5.375000

c = d.groupby('Age')['ReadingAbility'].agg(['size','sum'])
print (c)
     size  sum
Age           
3       1    0
4       1    9
5       3   14
6       2   12
7       1    8
8       2    2

e = c.rsub(c.sum())
e = e['sum'] / e['size']
print (e)
Age
3    5.000000
4    4.000000
5    4.428571
6    4.125000
7    4.111111
8    5.375000
dtype: float64

时间安排:

np.random.seed(45)
N = 100000
d = pd.DataFrame(np.random.randint(1000, size=(N, 2)), columns=['Age', 'ReadingAbility']) 
#print (d)


In [30]: %timeit (d.groupby('Age').apply(lambda x: d.loc[d['Age']!=x['Age'].iat[0], 'ReadingAbility'].mean()))
1 loop, best of 3: 1.27 s per loop


In [31]: %%timeit
    ...: c = d.groupby('Age')['ReadingAbility'].agg(['size','sum'])
    ...: #print (c)
    ...: e = c.sub(c.sum())
    ...: e = e['sum'] / e['size']
    ...: 
100 loops, best of 3: 6.28 ms per loop

我想你可以接受

df = pd.DataFrame([[1,10], [2,4],[1, 9], [2,3]], columns=['Age', 'ReadingAbility'])
res = df.loc[df['Age'] != 1].groupby('Age').apply(lambda x: x['ReadingAbility'].mean())
print res

返回:

Age : 2 3.5

相关问题 更多 >