微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

python – 使用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.

我究竟做错了什么?

解决方法:

transform用于与原始DataFrame相同的系列,以获得更好的性能,例如应用解决方案:

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

一个测试 – 删除索引名称 – 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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐