我有一个按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
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] 举报,一经查实,本站将立刻删除。