繁体   English   中英

使用pandas选择满足特定条件的组中的所有元素

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM