2016-07-26 5 views
6

私は3つの簡単な例から始めましょう:予想通りなぜgroupby sumはbooleanをintまたはfloatに変換しませんか?

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 

また期待どおりです。

enter image description here

私はバグを考えている:しかし、私groupby(['X', 'Y']).sum()

enter image description here

場合、私はそれが見えるように期待しました。別の説明がありますか? @の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')) 

私は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

おそらく、あなたが 'df ['Z'] = df ['Z']。astype(int)'の後に期待しているものを得ているからです。それを報告して、 'pandas'の開発者がこの動作の理由を持っているかどうか確認してください。 –

+2

これは、['_cython_agg_blocks'](https://github.com/pydata/pandas/blob/master/pandas/core/groupby.py#L3128)が[' _try_cast_result']を呼び出す '_try_coerce_and_cast_result'(https: //github.com/pydata/pandas/blob/master/pandas/core/internals.py#L536)元の値と同じdtype *の結果を返そうとします(この場合、 'bool')。 – unutbu

+1

@unutbu私はその決定のメリットを見ることができます。しかし、これは、グループ集約を使用する場合、常に期待しているタイプとしてキャストすべきであることを意味しているようです。質問、回答として投稿することができますので、回答として表示されますか?どうも! – piRSquared

答えて

4

これが発生するため、結果、元の値と同じDTYPEのを返そうと_try_cast_resultを呼び出し_cython_agg_blocksコール_try_coerce_and_cast_result(この場合には、bool)。

これは、Zにdtype bool(すべてのグループにTrue値が1つしかありません)がある場合に少し奇妙なものを返します。いずれかのグループに2つ以上のTrue値がある場合、_try_cast_resultは2を変換しないため、結果の値は浮動小数点になります。0をブール値に戻します。 ZはDTYPE intを持っているとき

_try_cast_resultは、より有用な何かを行います。内部的には、 df.groupby(['X', 'Y']).sum()で使用Cythonアグリゲータは、DTYPE floatresultを返します。ここで_try_cast_resultは結果をdtype intに返します。

関連する問題