在函数中包含应用于Pandas GroupBy对象的NaN值

时间:2017-06-28 20:11:55

标签: pandas-groupby

我想计算重复测量的平均值,并在一个或两个重复测定具有NaN值时返回NaN。我知道groupby排除了NaN值,但我花了一些时间才意识到apply正在做同样的事情。下面是我的代码示例。当两个重复项都缺少数据时,它只返回NaN。在这个例子中,我希望它返回样本1,分析2的NaN。相反,它的行为就好像我应用了np.nanmean并返回一个非零元素27.0。关于策略的任何想法都将NaN值包含在我正在应用的函数中?

    In[4]: import pandas as pd
    In[5]: import numpy as np
    In[6]: df = pd.DataFrame({'Sample ID': ['Sample 1', 'Sample 1', 'Sample 1', 'Sample 1', 'Sample 2', 'Sample 2', 'Sample 2', 'Sample 2'],
                              'Assay': ['Assay 1', 'Assay 1', 'Assay 2', 'Assay 2', 'Assay 1', 'Assay 1', 'Assay 2', 'Assay 2'],
                              'Replicate': [1, 2, 1, 2, 1, 2, 1, 2],
                              'Value': [34.0, 30.0, 27.0, np.nan, 16.0, 18.0, np.nan, np.nan]})
    In[7]: df
    Out[8]: 
      Sample ID    Assay  Replicate  Value
    0  Sample 1  Assay 1          1   34.0
    1  Sample 1  Assay 1          2   30.0
    2  Sample 1  Assay 2          1   27.0
    3  Sample 1  Assay 2          2    NaN
    4  Sample 2  Assay 1          1   16.0
    5  Sample 2  Assay 1          2   18.0
    6  Sample 2  Assay 2          1    NaN
    7  Sample 2  Assay 2          2    NaN

    In[9]: Group = df.groupby(['Sample ID', 'Assay'])
    In[10]: df2 = Group['Value'].aggregate(np.mean).unstack() 
    Out[82]: 
    Assay      Assay 1  Assay 2
    Sample ID                  
    Sample 1      32.0     27.0
    Sample 2      17.0      NaN

1 个答案:

答案 0 :(得分:0)

我认为问题出在mean函数执行转换期间。

来自documentation

  

包含其平均值所需数字的数组。如果a不是数组,   尝试转换。

我能够通过定义调用mean

的函数手动执行转换来使其工作
def aggregate_func(serie):
    return np.mean(serie.values)

并在aggregate调用上使用该函数,如下所示:

df2 = Group['Value'].aggregate(aggregate_func).unstack()

另一个选项是,如果您不提供可选的权重参数,则函数np.average的行为与np.mean相同。但看起来转换按预期工作。

使用它给了我预期的结果:

import pandas as pd
import numpy as np

df = pd.DataFrame({'Sample ID': ['Sample 1', 'Sample 1', 'Sample 1', 'Sample 1', 'Sample 2', 'Sample 2', 'Sample 2', 'Sample 2'],
                              'Assay': ['Assay 1', 'Assay 1', 'Assay 2', 'Assay 2', 'Assay 1', 'Assay 1', 'Assay 2', 'Assay 2'],
                              'Replicate': [1, 2, 1, 2, 1, 2, 1, 2],
                              'Value': [34.0, 30.0, 27.0, np.nan, 16.0, 18.0, np.nan, np.nan]})

Group = df.groupby(['Sample ID', 'Assay'])
df2 = Group['Value'].aggregate(np.average).unstack() 

结果

Assay       Assay 1 Assay 2
Sample ID       
Sample 1    32.0    NaN
Sample 2    17.0    NaN