【问题标题】:How can I compute the mean, dropping NaN and outliers from the dataframe in this format?如何计算平均值,以这种格式从数据框中删除 NaN 和异常值?
【发布时间】:2019-08-17 17:41:24
【问题描述】:

我有一个格式如下的数据框:

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 分数,然后返回值列表,如下所示:

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)]

当我尝试批量工作时会出现一些问题(我确信它们会出现,因为我习惯于使用循环进行编程,并且在 Pandas 中必须有一种“智能”的方式来执行此操作。 )

当存在 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 分数问题更大。我确定这是一个常见问题,但我不知道如何解决。

【问题讨论】:

  • NaN改成0怎么样?
  • 我想你的问题已经回答了here
  • 嗨 AhshayNevrekar,如果我这样做,平均值会受到影响。在这种情况下,“”、0.0 或 NaN 代表无条目。
  • 嗨 yochay magan,您发布的链接是一维序列,我可以使用 dropna 方法解决。

标签: pandas numpy scipy


【解决方案1】:

你可以使用:

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

【讨论】:

    猜你喜欢
    • 2021-02-27
    • 2023-02-05
    • 1970-01-01
    • 2021-06-22
    • 2022-01-07
    • 2011-07-25
    • 2020-08-21
    • 1970-01-01
    • 2017-09-24
    相关资源
    最近更新 更多