【问题标题】:dataframe mean calculation -> values that differ >20% from the median should be excluded from the mean-computation数据框均值计算 -> 与中位数相差 >20% 的值应从均值计算中排除
【发布时间】:2020-10-08 12:57:56
【问题描述】:

但是,我想计算数据框 y_2010、y_2011、y_2012、y_2013、y_2014 列的逐行平均值(每年的能源使用数据):

  • 与中位数(五个值中)相差超过 20% 的值应从平均值计算中排除。
  • 如果每行中剩余的值少于两个(在上述条件之后),则平均值设置为 NaN,因为一个值不足以获得可靠的平均值 -> 因此只能为包含两个值的行计算平均值或以上“20% 差异条件”之后的更多值。 (参见 ID(36):在第一个条件之后仍然有一个值,但这对于可靠的平均值来说还不够,因此将其设置为 NaN)

计算 5 列的平均值很容易,但我坚持定义条件“如果中值*0.8

所以我试图只计算没有“异常值”的数据行的平均值。

初始df:

ID  y_2010   y_2011   y_2012  y_2013  y_2014
23   22631  21954.0  22314.0   22032   21843
43   27456  29654.0  28159.0   28654    2000
36   61200      NaN      NaN   31895    1600
87   87621  86542.0  87542.0   88456   86961
90   58951  57486.0   2000.0       0       0
98   24587  25478.0      NaN   24896   25461

所需的df:

   ID  y_2010   y_2011   y_2012  y_2013  y_2014      mean
0  23   22631  21954.0  22314.0   22032   21843   22154.8
1  43   27456  29654.0  28159.0   28654    2000  28480.75
2  36   61200      NaN      NaN   31895    1600       NaN
3  87   87621  86542.0  87542.0   88456   86961   87424.4
4  90   58951  57486.0   2000.0       0       0       NaN
5  98   24587  25478.0      NaN   24896   25461   25105.5

到目前为止已尝试过的代码(我一直在努力获得正确的条件并将它们应用于数据框):

import pandas as pd
import numpy as np

df = pd.DataFrame({"ID": [23,43,36,87,90,98],
               "y_2010": [22631,27456,61200,87621,58951,24587], 
               "y_2011": [21954,29654,np.nan,86542,57486,25478],  
               "y_2012": [22314,28159,np.nan,87542,2000,np.nan],  
               "y_2013": [22032,28654,31895,88456,0,24896,],
               "y_2014": [21843,2000,1600,86961,0,25461]})
print(df)

a = df.loc[:, ['y_2010','y_2011','y_2012','y_2013', 'y_2014']]

# calculate median
median = a.median(1)
print(median)

# where condition is violated
mask = a.lt(median*.8, axis=0) | a.gt(median*1.2, axis=0)



【问题讨论】:

  • ID 为 90 的行的平均值也应该设置为 NaN 对吧?
  • 当然,你完全正确!对不起 ;) 一开始我一定忽略了零。

标签: python pandas mean median outliers


【解决方案1】:

我认为你的面具是对的,那么你可以从那里试试这个:

col_mean = a[~mask].mean(axis=1)
nan_mask = ~(mask.sum(axis=1) >= 2)

a["mean"] = col_mean.where(nan_mask, other=np.NaN)
print(a)

输出:

   y_2010   y_2011  y_2012  y_2013  y_2014  mean
0   22631   21954.0 22314.0 22032   21843   22154.80
1   27456   29654.0 28159.0 28654   2000    28480.75
2   61200   NaN     NaN     31895   1600    NaN
3   87621   86542.0 87542.0 88456   86961   87424.40
4   58951   57486.0 2000.0  0       0       NaN
5   24587   25478.0 NaN     24896   25461   25105.50

【讨论】:

  • 没错!我不熟悉 '~' 运算符,但这种方式非常简洁。
猜你喜欢
  • 2014-12-02
  • 2018-10-26
  • 2015-09-10
  • 2020-09-18
  • 2021-06-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多