dataframe 均值计算 -> 与中位数相差 >20% 的值应从均值计算中排除
dataframe mean calculation -> values that differ >20% from the median should be excluded from the mean-computation
我想计算数据帧的 y_2010、y_2011、y_2012、y_2013、y_2014 列的行平均值(能量每年使用数据),但是:
- 与(五个值中的)中位数相差超过 20% 的值应从均值计算中排除。
- 如果每行中剩下的值少于两个值(在上述条件之后),则将平均值设置为 NaN,因为一个值不足以获得可靠的平均值 -> 因此只能为满足以下条件的行计算平均值在上面的“20% 差异条件”之后包含两个或更多值。 (参见 ID(36):在第一个条件之后仍保留一个值,但这对于可靠均值来说还不够,因此将其设置为 NaN)
计算 5 列的平均值很容易,但我坚持定义条件 'if median*0.8 <= data row <= median*1,2 then mean ==边界内值的平均值并且存在 2 个或更多值。
所以我试图只计算没有 'outliers' 的数据行的平均值。
初始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)
我觉得你的面具是对的,那么你可以试试这个:
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
我想计算数据帧的 y_2010、y_2011、y_2012、y_2013、y_2014 列的行平均值(能量每年使用数据),但是:
- 与(五个值中的)中位数相差超过 20% 的值应从均值计算中排除。
- 如果每行中剩下的值少于两个值(在上述条件之后),则将平均值设置为 NaN,因为一个值不足以获得可靠的平均值 -> 因此只能为满足以下条件的行计算平均值在上面的“20% 差异条件”之后包含两个或更多值。 (参见 ID(36):在第一个条件之后仍保留一个值,但这对于可靠均值来说还不够,因此将其设置为 NaN)
计算 5 列的平均值很容易,但我坚持定义条件 'if median*0.8 <= data row <= median*1,2 then mean ==边界内值的平均值并且存在 2 个或更多值。
所以我试图只计算没有 'outliers' 的数据行的平均值。
初始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)
我觉得你的面具是对的,那么你可以试试这个:
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