Why doesn't groupby sum convert boolean to int or float?
<p>I'll start with 3 simple examples:</p>

<pre><code>pd.DataFrame([[True]]).sum()

0    1
dtype: int64
</code></pre>

<hr>

<pre><code>pd.DataFrame([True]).sum()

0    1
dtype: int64
</code></pre>

<hr>

<pre><code>pd.Series([True]).sum()

1
</code></pre>

<hr>

<p>All of these are as expected.  Here is a more complicated example.</p>

<pre><code>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
</code></pre>

<p>Also as expected.  However, if I <code>groupby(['X', 'Y']).sum()</code></p>

<p><a href="https://i.stack.imgur.com/UlT3T.png" rel="noreferrer"><img src="https://i.stack.imgur.com/UlT3T.png" alt="enter image description here"></a></p>

<p>I expected it to look like:</p>

<p><a href="https://i.stack.imgur.com/uGlNm.png" rel="noreferrer"><img src="https://i.stack.imgur.com/uGlNm.png" alt="enter image description here"></a></p>

<p>I'm thinking bug.  Is there another explanation?</p>

<hr>

<p>Per @unutbu's answer</p>

<p>pandas is trying to recast as original dtypes.  I had thought that maybe the group by I'd performed didn't really groupby anything.  So I tried this example to test out the idea.</p>

<pre><code>df = pd.DataFrame([
        ['a', 'A', False],
        ['a', 'B', False],
        ['a', 'C', True],
        ['b', 'A', False],
        ['b', 'B', False],
        ['b', 'C', False],
    ], columns=list('XYZ'))
</code></pre>

<p>I'll <code>groupby('X')</code> and <code>sum</code>.  If @unutbu is correct, these sums should be <code>1</code> and <code>0</code> and are castable to <code>bool</code>, therefore we should see <code>bool</code></p>

<pre><code>df.groupby('X').sum()
</code></pre>

<p><a href="https://i.stack.imgur.com/Tunph.png" rel="noreferrer"><img src="https://i.stack.imgur.com/Tunph.png" alt="enter image description here"></a></p>

<p>Sure enough... <code>bool</code></p>

<p>But if the process is the same but the values are slightly different.</p>

<pre><code>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()
</code></pre>

<p><a href="https://i.stack.imgur.com/5wh3K.png" rel="noreferrer"><img src="https://i.stack.imgur.com/5wh3K.png" alt="enter image description here"></a></p>

<p>lesson learned.  Always use <code>astype(int)</code> or something similar when doing this.</p>

<pre><code>df.groupby('X').sum().astype(int)
</code></pre>

<p>gives consistent results for either scenario.</p>