我有以下格式的数据框:
Original Dataframe
| x | value1 | value2 | value3 | value4
---|-----|----------|----------|----------|-----------
0 | 1 | 1 | NaN | 3 | 1
1 | 2 | 4 | NaN | 1 | NaN
2 | 3 | 2 | 6 | 1 | 2
3 | 4 | 1 | 1 | 2 | 1
我的目标是得出每行的平均值,除去NaN并消除异常值。目标是达到具有以下格式的新数据框:
Desired Dataframe
| x | mean (after dropping the NaN and the outliers)*
---|-----|--------
0 | 1 | a
1 | 2 | b
2 | 3 | c
3 | 4 | d
*请注意,a,b,c,d是平均值(我没有计算结果)
达到结果后的最终目标是随着时间的推移打印图形以显示值。
使用单个值列表,例如等效于一列值和一列索引,我可以执行所有操作:删除NaN,计算Z分数,然后返回值列表,如下所示:< / p>
import pandas as pd
import numpy as np
from scipy import stats
data = {'value': [1, 2, 15, np.NaN, 2, 2, 2, 3, 1, 1],
'x': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]}
df = pd.DataFrame(data)
df.dropna(inplace=True)
df = df[(np.abs(stats.zscore(df['return'])) < 2)]
当我尝试批量工作时会出现一些问题(并且我相信它们会出现是因为我习惯于使用循环进行编程,并且在熊猫中必须有一种“智能”方式来执行此操作)。 )
当存在NaN值时,我无法计算Z分数。我收到此错误:
/home/jupyterlab/conda/lib/python3.6/site-packages/ipykernel_launcher.py:14: RuntimeWarning: invalid value encountered in less
所以我知道我需要消除NaN。但是我不能以这种数据帧格式进行操作,因为这将意味着消除行或列,从而导致信息丢失。
我尝试不成功的另一种方法是将该表转换为长格式,这意味着我将拥有:
| x | valueName | actualValue
---|-----|-------------|--------------
0 | 1 | value1 | 1
1 | 1 | value2 | NaN
... ... ... ...
2 | 2 | value2 | 4
3 | 2 | value2 | NaN
这使我放弃了Nan,但是要使用Z得分则比较麻烦。我敢肯定这是一个普遍的问题,但是我不知道该怎么解决。
答案 0 :(得分:0)
您可以使用:
from scipy import stats
#reshape to MultiIndex Series for remove NaNs
s = df.set_index('x').stack()
print (s)
x
1 value1 1.0
value3 3.0
value4 1.0
2 value1 4.0
value3 1.0
3 value1 2.0
value2 6.0
value3 1.0
value4 2.0
4 value1 1.0
value2 1.0
value3 2.0
value4 1.0
dtype: float64
#count zsore by first level of group - by x
s1 = s.groupby(level=0).transform(lambda x: np.abs(stats.zscore(x)))
print (s1)
x
1 value1 0.707107
value3 1.414214
value4 0.707107
2 value1 1.000000
value3 1.000000
3 value1 0.390567
value2 1.692456
value3 0.911322
value4 0.390567
4 value1 0.577350
value2 0.577350
value3 1.732051
value4 0.577350
#filter by condition and get mean by first level x, convert to DataFrame
s2 = s[s1 < 2].mean(level=0).reset_index(name='mean')
print (s2)
x mean
0 1 1.666667
1 2 2.500000
2 3 2.750000
3 4 1.250000