Skip to content

Commit 88f54fb

Browse files
committed
BUG: pivot_table always returns a DataFrame
Before this commit, if * `values` is not list like * `columns` is `None` * `aggfunc` is not instance of `list` `pivot_table` returns a `Series`. This commit adds checking for `columns.nlevels` is greater than 1 to prevent from casting `table` to a `Series`. This will fix pandas-dev#4386.
1 parent bec5bdb commit 88f54fb

File tree

3 files changed

+41
-1
lines changed

3 files changed

+41
-1
lines changed

Diff for: doc/source/whatsnew/v0.20.0.txt

+1
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,4 @@ Performance Improvements
8181
Bug Fixes
8282
~~~~~~~~~
8383

84+
- Bug in ``pivot_table`` returns ``Series`` in specific circumstance (:issue:`4386`)

Diff for: pandas/tools/pivot.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,8 @@ def pivot_table(data, values=None, index=None, columns=None, aggfunc='mean',
169169
margins_name=margins_name)
170170

171171
# discard the top level
172-
if values_passed and not values_multi and not table.empty:
172+
if values_passed and not values_multi and not table.empty and \
173+
(table.columns.nlevels > 1):
173174
table = table[values[0]]
174175

175176
if len(index) == 0 and len(columns) > 0:

Diff for: pandas/tools/tests/test_pivot.py

+38
Original file line numberDiff line numberDiff line change
@@ -854,6 +854,44 @@ def test_categorical_margins(self):
854854
table = data.pivot_table('x', 'y', 'z', margins=True)
855855
tm.assert_frame_equal(table, expected)
856856

857+
def test_pivot_table_not_series(self):
858+
# GH 4386
859+
# pivot_table always returns a DataFrame
860+
# when values is not list like and columns is None
861+
# and aggfunc is not instance of list
862+
df = DataFrame({'col1': [3, 4, 5],
863+
'col2': ['C', 'D', 'E'],
864+
'col3': [1, 3, 9]})
865+
866+
result = df.pivot_table('col1', index=['col3', 'col2'], aggfunc=np.sum)
867+
m = MultiIndex.from_arrays([[1, 3, 9],
868+
['C', 'D', 'E']],
869+
names=['col3', 'col2'])
870+
expected = DataFrame([3, 4, 5],
871+
index=m, columns=['col1'])
872+
873+
tm.assert_frame_equal(result, expected)
874+
875+
result = df.pivot_table(
876+
'col1', index='col3', columns='col2', aggfunc=np.sum
877+
)
878+
expected = DataFrame([[3, np.NaN, np.NaN],
879+
[np.NaN, 4, np.NaN],
880+
[np.NaN, np.NaN, 5]],
881+
index=Index([1, 3, 9], name='col3'),
882+
columns=Index(['C', 'D', 'E'], name='col2'))
883+
884+
tm.assert_frame_equal(result, expected)
885+
886+
result = df.pivot_table('col1', index='col3', aggfunc=[np.sum])
887+
m = MultiIndex.from_arrays([['sum'],
888+
['col1']])
889+
expected = DataFrame([3, 4, 5],
890+
index=Index([1, 3, 9], name='col3'),
891+
columns=m)
892+
893+
tm.assert_frame_equal(result, expected)
894+
857895

858896
class TestCrosstab(tm.TestCase):
859897

0 commit comments

Comments
 (0)