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

Including NaN values in function applied to Pandas GroupBy object

我想计算重复测量的平均值和 return 当一个或两个重复具有 NaN 值时的 NaN。我知道 groupby 排除了 NaN 值,但我花了一些时间才意识到 apply 也在做同样的事情。下面是我的代码示例。当两个副本都有缺失数据时,它只有 returns NaN。在这个例子中,我希望样本 1、分析 2 为 return NaN。相反,它的行为就像我应用了 np.nanmean 和 return 一个非零元素 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

我认为问题出在 mean 函数执行时发生的转换过程中。

来自documentation

Array containing numbers whose mean is desired. If a is not an array, a conversion is attempted.

我能够通过定义调用 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