改善pandas中的设置值

时间:2018-03-02 01:33:22

标签: python pandas dataframe

我想为组功能添加一些列(std,mean ...),下面的代码可以工作,但数据集非常大而且性能很差。改善代码有什么好主意吗?感谢

import pandas as pd

df = pd.DataFrame([[1,2,1], [1,2,2], [1,3,3], [1,3,4],[2,8,9], [2,11,11]], columns=['A', 'B', 'C'])
df['mean'] = 0

df2 = df.groupby('A')
for a, group in df2:
    mean = group['C'].mean()
    df.loc[df['A'] == a, 'mean'] = mean

df
'''
     A   B   C  mean
0   1   2   1   2.5
1   1   2   2   2.5
2   1   3   3   2.5
3   1   3   4   2.5
4   2   8   9   10.0
5   2   11  11  10.0
'''

3 个答案:

答案 0 :(得分:5)

Pandas'groupby.transform负责在原始索引中广播聚合统计数据。这使它非常适合您的目的,应该被视为执行此任务的惯用方法。

流水线解决方案,使用新列

生成df的副本
df.assign(Mean=df.groupby('A').C.transform('mean'))

   A   B   C  Mean
0  1   2   1   2.5
1  1   2   2   2.5
2  1   3   3   2.5
3  1   3   4   2.5
4  2   8   9  10.0
5  2  11  11  10.0

到位分配

df['Mean'] = df.groupby('A').C.transform('mean')
df

   A   B   C  Mean
0  1   2   1   2.5
1  1   2   2   2.5
2  1   3   3   2.5
3  1   3   4   2.5
4  2   8   9  10.0
5  2  11  11  10.0

或者,您可以使用pd.factorizenp.bincount

f, u = pd.factorize(df.A.values)
totals = np.bincount(f, df.C.values)
counts = np.bincount(f)
df.assign(Mean=(totals / counts)[f])

   A   B   C  Mean
0  1   2   1   2.5
1  1   2   2   2.5
2  1   3   3   2.5
3  1   3   4   2.5
4  2   8   9  10.0
5  2  11  11  10.0

答案 1 :(得分:3)

这是一种方式:

s = df.groupby('A')['C'].mean()

df['mean'] = df['A'].map(s)

#    A   B   C  mean
# 0  1   2   1   2.5
# 1  1   2   2   2.5
# 2  1   3   3   2.5
# 3  1   3   4   2.5
# 4  2   8   9  10.0
# 5  2  11  11  10.0

<强>解释

  • 首先,groupby'A'并计算'C'的mean。这将创建一个系列,其中包含“A”中的索引唯一条目和所需的值。
  • 其次,map此系列文章在您的数据框中。这是可能的,因为pd.Series.map可以将一系列作为输入。

答案 2 :(得分:2)

您可以使用索引

调用mean
df.assign(mean=df.A.map(df.set_index('A').C.mean(level=0)))
Out[28]: 
   A   B   C  mean
0  1   2   1   2.5
1  1   2   2   2.5
2  1   3   3   2.5
3  1   3   4   2.5
4  2   8   9  10.0
5  2  11  11  10.0

或使用get

df['mean']=df.set_index('A').C.mean(level=0).get(df.A).values
df
Out[35]: 
   A   B   C  mean
0  1   2   1   2.5
1  1   2   2   2.5
2  1   3   3   2.5
3  1   3   4   2.5
4  2   8   9  10.0
5  2  11  11  10.0