【问题标题】:Pandas groupby apply strange behavior when NaN's in group column当 NaN 在组列中时,Pandas groupby 会应用奇怪的行为
【发布时间】:2020-09-17 09:23:43
【问题描述】:

我遇到了一些意想不到的 Pandas groupby-apply 结果,但我无法找出确切的原因。

下面我必须是除了 2 个值的排序之外的数据帧。 df1 产生我期望的结果,但 df2 产生完全不同的结果。

import numpy as np

df1 = pd.DataFrame({'group_col': [0.0, np.nan, 0.0, 0.0], 'value_col': [2,2,2,2]})
df2 = pd.DataFrame({'group_col': [np.nan, 0.0, 0.0, 0.0], 'value_col': [2,2,2,2]})

df1:

   group_col  value_col
0        0.0          2
1        NaN          2
2        0.0          2
3        0.0          2

df2:

   group_col  value_col
0        NaN          2
1        0.0          2
2        0.0          2
3        0.0          2

当我按group_col 分组并对每个组的value_col 进行value_counts 时,包括重新索引以将所有可能的值包含在结果中,我得到的df1 如下:

df1.groupby('group_col').value_col.apply(lambda x: x.value_counts().reindex(index=[1,2,3]))

group_col   
0.0        1    NaN
           2    3.0
           3    NaN
Name: value_col, dtype: float64

它正确地找到 1 个组并返回一个多索引系列,其中每个可能的值都有 value_counts。但是当我在 df2 上运行相同的程序时,我得到了完全不同的结果:

0    NaN
1    NaN
2    3.0
3    NaN
Name: value_col, dtype: float64

这里的结果包含一个与原始 DataFrame 匹配的索引,而不是我期望的多索引。我认为这可能与以 np.nan 开头的 group 列有关,但后来我尝试删除最后一行并再次得到预期的结果,所以显然原因是其他原因。

df2.head(3).groupby('group_col').value_col.apply(lambda x: x.value_counts().reindex(index=[1,2,3]))

group_col   
0.0        1    NaN
           2    2.0
           3    NaN
Name: value_col, dtype: float64

这可能是什么原因造成的?

【问题讨论】:

    标签: python pandas numpy dataframe pandas-groupby


    【解决方案1】:

    让我们从一些简单的分组计算开始,以了解 pandas 是如何处理它的。

    在以下情况下,分组键用作生成的Series 对象中的索引。原始索引已被删除。

    In [4]: df1.groupby('group_col')['value_col'] \
       ...: .apply(lambda x: {'sum': x.sum(), 'mean': x.mean()})
    Out[4]: 
    group_col
    0.0        sum     6.0
               mean    2.0
    Name: value_col, dtype: float64
    
    In [5]: df2.groupby('group_col')['value_col'] \
       ...: .apply(lambda x: {'sum': x.sum(), 'mean': x.mean()})
    Out[5]: 
    group_col
    0.0        sum     6.0
               mean    2.0
    Name: value_col, dtype: float64
    

    在下一种情况下,原始DataFrame 的索引被保留。结果Series中不包含分组键。

    In [6]: df1.groupby('group_col')['value_col'].apply(lambda x: x / len(x))
    Out[6]: 
    0    0.666667
    1         NaN
    2    0.666667
    3    0.666667
    Name: value_col, dtype: float64
    
    In [7]: df2.groupby('group_col')['value_col'].apply(lambda x: x / len(x))
    Out[7]: 
    0         NaN
    1    0.666667
    2    0.666667
    3    0.666667
    Name: value_col, dtype: float64
    

    是什么让 pandas 在生成组合对象的索引时表现不同?

    实际上,这是基于索引是否被聚合改变。当原始对象和结果对象的索引相同时,它选择重用原始索引。另一方面,当索引与原始对象不同时,它使用索引中的组键形成MultiIndex

    现在,回到问题,请注意索引已更改为df1。对于组键0.0,原始chunk的索引为[0, 2, 3],聚合后为[1, 2, 3]。但是,对于df2,原来的索引是[1, 2, 3],一不小心没有被聚合改变。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-25
      • 1970-01-01
      • 1970-01-01
      • 2017-07-19
      • 2019-11-11
      • 2022-01-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多