在 Pandas 中对分组后的数据选择前 n 个项目,并计算它们的平均值。

3

我有以下数据框:

df = pd.DataFrame({'Value': [0, 1, 2,3, 4,5,6,7,8,9],'Name': ['John', 'Jim', 'John','Jim', 'John','Jim','Jim','John','Jim','John']})
df
    Value   Name
0   0   John
1   1   Jim
2   2   John
3   3   Jim
4   4   John
5   5   Jim
6   6   Jim
7   7   John
8   8   Jim
9   9   John

我想通过Name选择排名前n的项目,并从Value列中计算平均值。

我尝试了以下方法:

df['Top2Mean'] = df.groupby(['Name'])['Value'].nlargest(2).transform('mean')

但是遇到了以下错误:

ValueError: 转换无法生成聚合结果

我的预期结果是在 John 后面加上值为 8,在 Jim 后面加上值为 7 的新列,该列名为Top2Mean

提前感谢!

1个回答

3

我们在 level=0 上计算 mean,然后将计算出的平均值映射到 Name 列以广播聚合结果。

top2 = df.groupby('Name')['Value'].nlargest(2).mean(level=0)
df['Top2Mean'] = df['Name'].map(top2)

如果我们需要按多个列进行分组,例如 NameCity,那么我们需要在 level=[Name, City] 上使用 mean 平均值,并使用 MultiIndex.map 映射计算出的平均值。
c = ['Name', 'City']
top2 = df.groupby(c)['Value'].nlargest(2).mean(level=c)
df['Top2Mean'] = df.set_index(c).index.map(top2)

使用自定义 lambda 函数的 `groupby` 和 `transform` 的另一种方法。
df['Top2Mean'] = df.groupby('Name')['Value']\
                   .transform(lambda v: v.nlargest(2).mean())

   Value  Name  Top2Mean
0      0  John         8
1      1   Jim         7
2      2  John         8
3      3   Jim         7
4      4  John         8
5      5   Jim         7
6      6   Jim         7
7      7  John         8
8      8   Jim         7
9      9  John         8

谢谢!有时我有多个分组列,那么这行代码 df['Top2Mean'] = df['Name'].map(top2) 应该如何调整? - SOK
@SOK 你能否举个这样的场景的小例子? - Shubham Sharma
例如,如果top2计算为:top2 = df.groupby(['Name','City'])['Value'].nlargest(2).mean(level=0),我该如何映射df['Top2Mean']以包括City?@Shubham Sharma - SOK
1
谢谢!我现在会尝试这个方法和另一种选择。 - SOK
1
替代方案非常好用!而且只需要一行代码,非常简单! - SOK
1
@SOK 很高兴它对你有用。愉快编程! - Shubham Sharma

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接