我将从三个简单的例子开始:
pd.DataFrame([[True]]).sum()
0 1
dtype: int64
pd.DataFrame([True]).sum()
0 1
dtype: int64
pd.Series([True]).sum()
1
这些都是预期的结果。这里有一个更复杂的示例。
df = pd.DataFrame([
['a', 'A', True],
['a', 'B', False],
['a', 'C', True],
['b', 'A', True],
['b', 'B', True],
['b', 'C', False],
], columns=list('XYZ'))
df.Z.sum()
4
同样符合预期。但是,如果我使用 groupby(['X', 'Y']).sum()
,它会变成这个样子:
我以为结果应该是这个样子的:
我认为这是一个错误。还有其他的解释吗?
根据 @unutbu 的回答
pandas 试图重新编码为原始 dtype。我曾认为也许我执行的 group by 操作并没有真正分组任何内容。所以我尝试了这个示例,来测试这个想法。
df = pd.DataFrame([
['a', 'A', False],
['a', 'B', False],
['a', 'C', True],
['b', 'A', False],
['b', 'B', False],
['b', 'C', False],
], columns=list('XYZ'))
我将对'X'进行“分组”和“求和”。如果@unutbu正确,这些总和应为1和0,并且可转换为“bool”类型,因此我们应该看到“bool”。
df.groupby('X').sum()
果然...bool
但如果过程相同,但值略有不同呢?
df = pd.DataFrame([
['a', 'A', True],
['a', 'B', False],
['a', 'C', True],
['b', 'A', False],
['b', 'B', False],
['b', 'C', False],
], columns=list('XYZ'))
df.groupby('X').sum()
得出的教训是,做这件事时总是要使用astype(int)
或类似的东西。
df.groupby('X').sum().astype(int)
无论是哪种场景,都可以获得一致的结果。
df['Z'] = df['Z'].astype(int)
后得到了预期的结果。去报告一下,看看pandas
的开发人员是否有这种行为的原因。 - Alicia Garcia-Raboso_cython_agg_blocks
调用了_try_coerce_and_cast_result
,该函数又调用_try_cast_result
,后者试图返回与原始值(在本例中为bool
)相同dtype的结果。 - unutbu