Pandas groupby在组列中的NaN时,应用了奇怪的行为。

问题描述 投票:3回答:1

我遇到了一些意想不到的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_counts的 value_col 每一个组,包括重新索引以包括所有可能的值,我得到以下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 开头的组列有关,但后来我试着删除最后一行,我又得到了预期的结果,所以显然是其他原因造成的。

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个回答
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,原始块的索引是 [0, 2, 3]而它是 [1, 2, 3] 聚合后。然而,对于 df2,原来的指数是 [1, 2, 3],意外的是,它并没有被聚集改变。

© www.soinside.com 2019 - 2024. All rights reserved.