【问题标题】:conditionally replace grouped values有条件地替换分组值
【发布时间】:2021-10-15 01:26:30
【问题描述】:

假设我有下面的df:

df = pd.DataFrame({'id':[1,1,1,1,2,2,2,2,3,3,3,3],'category' : ['A','A','A','A','B','B','B','B','C','C','C','C'],'price':[1,2,3,10,2,3,4,20,1,10,1,4]})
print(df)
     id    category value
0    1        A      1
1    1        A      2
2    1        A      3
3    1        A     10
4    2        B      2
5    2        B      3
6    2        B      4
7    2        B     20
8    3        C      1
9    3        C     10
10   3        C      1
11   3        C      4

对于相同 id 和 category 的 values('price'),当它们不满足条件时,我想将它们替换为其余值的平均值。例如,对于 id 1 和类别 A,我想用其他三个值 (1,2,3) 的平均值替换 10。我尝试了很多东西,但似乎没有任何效果。关于如何解决这个问题的任何建议?谢谢

【问题讨论】:

  • 请明确且详尽。具体条件是什么?另外,请提供预期的输出。
  • 谢谢。因此,条件是如果一个值比其他值的平均值大/小 2 倍,则将其替换为这些值的平均值。预期的输出是将这 4 个值中每组的“异常值”替换为该特定组的平均值。
  • 大于其他值的平均值(很难做到)或组的平均值?
  • 第一个案例。我想检查每个组是否存在某种类型的测量误差,并用更合理的值替换异常值。
  • 我说的是检测异常值的条件。它是否可以根据组的平均值检测然后用非异常值的平均值替换?非异常值均值条件的问题在于,您基本上需要在解决它之前知道解决方案;)

标签: python pandas dataframe group-by


【解决方案1】:

这是一个解决方案,它根据组的平均值检测异常值,然后用非异常值的平均值替换它们:

means = df.groupby(['id', 'category'])['price'].transform('mean')
df['new_price'] = df['price'].where(~(df['price'].gt(2*means)|df['price'].lt(0.5*means)), float('nan'))
df['new_price'] = df['new_price'].where(~df['new_price'].isna(), df.groupby(['id', 'category'])['new_price'].transform('mean'))

# for debugging only
df['outlier'] = df['price'].where(~(df['price'].gt(2*means)|df['price'].lt(0.5*means)), float('nan')).isna()

输出:

    id category  price  new_price  outlier
0    1        A      1        2.5     True
1    1        A      2        2.0    False
2    1        A      3        3.0    False
3    1        A     10        2.5     True
4    2        B      2        4.0     True
5    2        B      3        4.0     True
6    2        B      4        4.0    False
7    2        B     20        4.0     True
8    3        C      1        4.0     True
9    3        C     10        4.0     True
10   3        C      1        4.0     True
11   3        C      4        4.0    False

【讨论】:

  • 谢谢,这正是我想要的。
  • 太好了,很高兴它有帮助!
【解决方案2】:

这将为您提供所有值的平均值

df.loc[(df['category'] == 'A')&(df['id'] == 1), ['price']].loc[df.loc[(df['category'] == 'A')&(df['id'] == 1), ['price']].values < df.loc[(df['category'] == 'A')&(df['id'] == 1), ['price']].values.max(), 'price'].mean()

【讨论】:

    猜你喜欢
    • 2014-08-23
    • 2012-01-03
    • 2016-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-28
    • 2014-01-09
    相关资源
    最近更新 更多