我想计算数据框a,b,c,d列的平均数,但是如果每个数据框行的四个值中有一个与这个平均数(四个值中的)相差20%以上,则必须将平均数设置为NaN。
计算4列的均值很容易,但我在定义 "如果均值*0.8 <=数据行中的一个值 <=均值*1,2,那么均值==NaN "这个条件时卡住了。
在这个例子中,ID:5和ID:87中的一个或多个值不符合区间,因此平均值被设置为NaN。(在计算平均数和对计算的平均数应用20%条件时,初始数据框中的NaN值被忽略)
所以我试图只计算没有 "异常值 "的数据行的平均值。
初始df:
ID a b c d
2 31 32 31 31
5 33 52 159 2
7 51 NaN 52 51
87 30 52 421 2
90 10 11 10 11
102 41 42 NaN 42
Desired df:
ID a b c d mean
2 31 32 31 31 31.25
5 33 52 159 2 NaN
7 51 NaN 52 51 51.33
87 30 52 421 2 NaN
90 10 11 10 11 10.50
102 41 42 NaN 42 41.67
代码:
import pandas as pd
import numpy as np
df = pd.DataFrame({"ID": [2,5,7,87,90,102],
"a": [31,33,51,30,10,41],
"b": [32,52,np.nan,52,11,42],
"c": [31,159,52,421,10,np.nan],
"d": [31,2,51,2,11,42]})
print(df)
a = df.loc[:, ['a','b','c','d']]
df['mean'] = (a.iloc[:,0:]).mean(1)
print(df)
b = df.mean.values[:,None]*0.8 < a.values[:,:] < df.mean.values[:,None]*1.2
print(b)
...
IIUC。
# extract related information
s = df.iloc[:,1:]
# calculate mean
mean = s.mean(1)
# where condition is violated
mask = s.lt(mean*.8, axis=0) | s.gt(mean*1.2, axis=0)
# mask where mask is True on any row
df['mean'] = mean.mask(mask.any(1))
输出。
ID a b c d mean
0 2 31 32.0 31.0 31 31.250000
1 5 33 52.0 159.0 2 NaN
2 7 51 NaN 52.0 51 51.333333
3 87 30 52.0 421.0 2 NaN
4 90 10 11.0 10.0 11 10.500000
5 102 41 42.0 NaN 42 41.666667