[英]select all elements in a group that meet a specific condition using pandas
我有一个按id
分组的df。 对于每个id
组,我想返回列a
大于该组的a
的平均值的所有行。 我尝试了以下方法:
df = pd.DataFrame(data = {"a": np.arange(10), "b": np.arange(10)[::-1], "c": np.random.choice(a = np.arange(10), size = 10)}, index = pd.Index(data = np.random.choice(a = [1,2,3], size = 10), name = "id"))
df.groupby("id").apply(lambda x: x[x.a > x.a.mean()])
这会引发ValueError:重复级别名称:分配给级别1的“id”已用于级别0。
我究竟做错了什么?
使用相同Series
transform
作为原始DataFrame
大小, DataFrame
获得更好的性能,例如apply
解决方案:
df = df[df['a'] > df.groupby("id")['a'].transform('mean')]
print (df)
a b c
id
2 5 4 3
2 6 3 2
1 7 2 3
3 8 1 0
3 9 0 5
细节 :
print (df.groupby("id")['a'].transform('mean'))
id
1 4.75
1 4.75
1 4.75
3 3.50
3 3.50
1 4.75
1 4.75
1 4.75
1 4.75
1 4.75
Name: a, dtype: float64
在您的解决方案中需要参数group_keys=False
以避免具有相同级别名称的MultiIndex
,因为索引名称中的id
:
df = df.groupby("id", group_keys=False).apply(lambda x: x[x.a > x.a.mean()])
如果first reset_index()
获取列名id
和索引名id
,但是有相同的值:
df = df.reset_index().groupby("id").apply(lambda x: x[x.a > x.a.mean()])
print (df)
id a b c
id
2 6 2 6 3 3
7 2 7 2 9
9 2 9 0 1
3 5 3 5 4 9
8 3 8 1 8
另一个测试 - 删除index name
- id
:
df = df.rename_axis(None)
print (df)
a b c
3 0 9 2
2 1 8 2
1 2 7 6
3 3 6 1
1 4 5 3
2 5 4 9
3 6 3 6
2 7 2 1
1 8 1 0
1 9 0 1
df = df.groupby(level=0).apply(lambda x: x[x.a > x.a.mean()])
print (df)
a b c
1 1 8 1 0
1 9 0 1
2 2 5 4 9
2 7 2 1
3 3 6 3 6
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.