用groupby替换值意味着

时间:2013-02-07 20:51:01

标签: python pandas pandas-groupby

我有一个DataFrame,其列包含一些带有各种负值的错误数据。我想替换值< 0表示他们所在组的平均值。

对于作为NA的缺失值,我会这样做:

data = df.groupby(['GroupID']).column
data.transform(lambda x: x.fillna(x.mean()))

但是如何在x < 0

等条件下执行此操作

谢谢!

4 个答案:

答案 0 :(得分:9)

使用@ AndyHayden的示例,您可以将groupby / transformreplace一起使用:

df = pd.DataFrame([[1,1],[1,-1],[2,1],[2,2]], columns=list('ab'))
print(df)
#    a  b
# 0  1  1
# 1  1 -1
# 2  2  1
# 3  2  2

data = df.groupby(['a'])
def replace(group):
    mask = group<0
    # Select those values where it is < 0, and replace
    # them with the mean of the values which are not < 0.
    group[mask] = group[~mask].mean()
    return group
print(data.transform(replace))
#    b
# 0  1
# 1  1
# 2  1
# 3  2

答案 1 :(得分:2)

这是一种方法(对于'b'列,在这个无聊的例子中):

In [1]: df = pd.DataFrame([[1,1],[1,-1],[2,1],[2,2]], columns=list('ab'))
In [2]: df
Out[2]: 
   a  b
0  1  1
1  1 -1
2  2  1
3  2  2

将这些负值替换为NaN,然后​​计算每组中的平均值(b):

In [3]: df['b'] = df.b.apply(lambda x: x if x>=0 else pd.np.nan)
In [4]: m = df.groupby('a').mean().b

然后在每行中使用apply,将每个NaN替换为其组意味着:

In [5]: df['b'] = df.apply(lambda row: m[row['a']]
                                       if pd.isnull(row['b'])
                                       else row['b'],
                           axis=1) 
In [6]: df
Out[6]: 
   a  b
0  1  1
1  1  1
2  2  1
3  2  2

答案 2 :(得分:1)

对于您的其他问题,有一个很好的示例。

df = pd.DataFrame({'A' : [1, 1, 2, 2], 'B' : [1, -1, 1, 2]})
gb = df.groupby('A')
def replace(g):
   mask = g < 0
   g.loc[mask] = g[~mask].mean()
   return g
gb.transform(replace)

链接:http://pandas.pydata.org/pandas-docs/stable/cookbook.html

答案 3 :(得分:1)

我遇到了同样的问题并提出了一个相当简单的解决方案

func = lambda x : np.where(x < 0, x.mean(), x)

df['Bad_Column'].transform(func)

请注意,如果您想要返回正确值的平均值(仅基于正值的平均值),您必须指定:

func = lambda x : np.where(x < 0, x.mask(x < 0).mean(), x)