为什么groupby sum不将boolean转换为int或float?

piR*_*red 9 python pandas

我将从3个简单的例子开始:

pd.DataFrame([[True]]).sum()

0    1
dtype: int64
Run Code Online (Sandbox Code Playgroud)
pd.DataFrame([True]).sum()

0    1
dtype: int64
Run Code Online (Sandbox Code Playgroud)
pd.Series([True]).sum()

1
Run Code Online (Sandbox Code Playgroud)

所有这些都是预期的.这是一个更复杂的例子.

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
Run Code Online (Sandbox Code Playgroud)

也如预期的那样.但是,如果我groupby(['X', 'Y']).sum()

在此输入图像描述

我希望它看起来像:

在此输入图像描述

我在想bug.有另一种解释吗?


Per @ unutbu的回答

大熊猫试图重铸为原始的dtypes.我曾经想过,也许我所表演的那个小组并没有真正的团结.所以我尝试了这个例子来测试这个想法.

df = pd.DataFrame([
        ['a', 'A', False],
        ['a', 'B', False],
        ['a', 'C', True],
        ['b', 'A', False],
        ['b', 'B', False],
        ['b', 'C', False],
    ], columns=list('XYZ'))
Run Code Online (Sandbox Code Playgroud)

我会groupby('X')sum.如果@unutbu是正确的,这些总和应该是10可投出的bool,因此我们应该看到bool

df.groupby('X').sum()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

果然... 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()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

学过的知识.astype(int)这样做时总是使用或类似的东西.

df.groupby('X').sum().astype(int)
Run Code Online (Sandbox Code Playgroud)

为两种情况提供一致的结果.

unu*_*tbu 8

这是因为_cython_agg_blocks调用_try_coerce_and_cast_result哪些调用_try_cast_result尝试返回与原始值相同的dtype的结果(在本例中bool).

Zdtype bool(并且所有组都没有超过一个True值)时,这会返回一些有点奇怪的东西.如果任何组具有2个或更多True值,则结果值为浮点数,因为 _try_cast_result不会将2.0转换回布尔值.

_try_cast_result做一些事情的时候更加有用Z具有D型int:在内部,由使用的用Cython聚合 df.groupby(['X', 'Y']).sum()一个回报result的D型float.然后,_try_cast_result将结果返回到dtype int.