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

时间:2016-07-26 00:21:39

标签: python pandas

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

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()

enter image description here

我希望它看起来像:

enter image description here

我在想bug。还有其他解释吗?

Per @ unutbu的回答

pandas试图重铸为原始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'))

groupby('X')sum。如果@unutbu是正确的,那么这些总和应该是10,并且可以投放到bool,因此我们应该看到bool

df.groupby('X').sum()

enter image description here

果然...... 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()

enter image description here

学到的经验教训。这样做时,请始终使用astype(int)或类似内容。

df.groupby('X').sum().astype(int)

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

1 个答案:

答案 0 :(得分:7)

这是因为_cython_agg_blocks调用_try_coerce_and_cast_result调用_try_cast_result,它会尝试返回与原始值相同的dtype 的结果(在这种情况下, bool)。

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

_try_cast_result具有dtype Z时,

int会更有用:内部使用的Cython聚合器 df.groupby(['X', 'Y']).sum()返回result dtype float。然后,_try_cast_result将结果返回给dtype int