Pandas数据框中满足特定条件的所有行的平均值

5

假设我有一个数据框:

    Code  Value
1   X     135
2   D     298
3   F     301
4   G     12
5   D     203
6   X     212
7   D     401
8   D     125

我希望在此数据框中创建一个新列,该列计算数据框中所有行的平均值,其中'Code'列中的值是每行相应的值。
例如,在第一行中,“Mean”列将查找Code为“X”的所有行的平均值。
2个回答

8
您可以这样使用 pd.Series.map()
df['Code_mean'] = df.Code.map(df.groupby(['Code']).Value.mean())

>>> df
Out[]:
  Code  Value  Code_mean
1    X    135     173.50
2    D    298     256.75
3    F    301     301.00
4    G     12      12.00
5    D    203     256.75
6    X    212     173.50
7    D    401     256.75
8    D    125     256.75

这种方法似乎比使用transform更快。


编辑:为回复评论添加基准测试

import pandas as pd
from string import ascii_letters

df = pd.DataFrame(columns=['Code', 'Value'])
df.Code = [ascii_letters[26:][i] for i in np.random.randint(0, 26, 10000)]
df.Value = np.random.randint(0, 1024, 10000)

>>> %%timeit
... df['Code_mean'] = df.Code.map(df.groupby(['Code']).Value.mean())
1000 loops, best of 3: 1.45 ms per loop

# Reinit df before next timeit

>>> %%timeit
... df.assign(Code_mean=df.groupby('Code').transform('mean'))
100 loops, best of 3: 2.31 ms per loop

然而在测试中,transform 对于较大的数据框(10^6 行)的结果更有利。

import pandas as pd
from string import ascii_letters

df = pd.DataFrame(columns=['Code', 'Value'])
df.Code = [ascii_letters[26:][i] for i in np.random.randint(0, 26, 1000000)]
df.Value = np.random.randint(0, 1024, 1000000)

>>> %%timeit
... df['Code_mean'] = df.Code.map(df.groupby(['Code']).Value.mean())
10 loops, best of 3: 95.2 ms per loop

# Reinit df before next timeit

>>> %%timeit
... df.assign(Code_mean=df.groupby('Code').transform('mean'))
10 loops, best of 3: 68.2 ms per loop

你发现哪种设置(每组行数/总行数)更快? - ayhan
性能在这里可能与输入大小有关。确实,对于具有4个组的8行数据,该方法更快,但是如果有更多的数据行,比如10^6,它将遭受严重影响。只值得注意。 - miradulo
10000行,26组,这次大约快了40%。 - FabienP
@FabienP 请说明您是如何进行基准测试的 - 我没有看到类似的结果。 - miradulo
@Mitch:包含基准测试,你说得对,有一个用于更大数据框的开关。阈值可能在10^5行左右。 - FabienP

1

在按代码分组后,transform 方法是一个很好的应用程序。

>>> df['Group_means'] = df.groupby('Code').transform('mean')
>>> df
  Code  Value  Group_means
0    X    135       173.50
1    D    298       256.75
2    F    301       301.00
3    G     12        12.00
4    D    203       256.75
5    X    212       173.50
6    D    401       256.75
7    D    125       256.75

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