-
-
Notifications
You must be signed in to change notification settings - Fork 18.4k
ENH: DataFrame.pivot accepts a list of values #18636
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
b74ee0f
a36f9e0
5f94728
3008d8e
b3ea1c2
539ffdc
d176585
6646798
ea77a97
1d6bf58
c000811
c750807
d3a7bec
c50b2dd
df2f0b0
bb85875
8f8b45f
99abef4
41ad9c0
2f5d6f7
516690c
e30fd1c
eb9d85f
786e5f7
8ea45f8
3825c9a
8e54fc9
e293741
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -371,6 +371,89 @@ def test_pivot_periods(self): | |
pv = df.pivot(index='p1', columns='p2', values='data1') | ||
tm.assert_frame_equal(pv, expected) | ||
|
||
@pytest.mark.parametrize('values', [ | ||
['baz', 'zoo'], np.array(['baz', 'zoo']), | ||
pd.Series(['baz', 'zoo']), pd.Index(['baz', 'zoo']) | ||
]) | ||
def test_pivot_with_list_like_values(self, values): | ||
# issue #17160 | ||
df = pd.DataFrame({'foo': ['one', 'one', 'one', 'two', 'two', 'two'], | ||
'bar': ['A', 'B', 'C', 'A', 'B', 'C'], | ||
'baz': [1, 2, 3, 4, 5, 6], | ||
'zoo': ['x', 'y', 'z', 'q', 'w', 't']}) | ||
|
||
result = df.pivot(index='foo', columns='bar', values=values) | ||
|
||
data = [[1, 2, 3, 'x', 'y', 'z'], | ||
[4, 5, 6, 'q', 'w', 't']] | ||
index = Index(data=['one', 'two'], name='foo') | ||
columns = MultiIndex(levels=[['baz', 'zoo'], ['A', 'B', 'C']], | ||
labels=[[0, 0, 0, 1, 1, 1], [0, 1, 2, 0, 1, 2]], | ||
names=[None, 'bar']) | ||
expected = DataFrame(data=data, index=index, | ||
columns=columns, dtype='object') | ||
tm.assert_frame_equal(result, expected) | ||
|
||
@pytest.mark.parametrize('values', [ | ||
['bar', 'baz'], np.array(['bar', 'baz']), | ||
pd.Series(['bar', 'baz']), pd.Index(['bar', 'baz']) | ||
]) | ||
def test_pivot_with_list_like_values_nans(self, values): | ||
# issue #17160 | ||
df = pd.DataFrame({'foo': ['one', 'one', 'one', 'two', 'two', 'two'], | ||
'bar': ['A', 'B', 'C', 'A', 'B', 'C'], | ||
'baz': [1, 2, 3, 4, 5, 6], | ||
'zoo': ['x', 'y', 'z', 'q', 'w', 't']}) | ||
|
||
result = df.pivot(index='zoo', columns='foo', values=values) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add a test with values as a tuple (it should fail) |
||
|
||
data = [[np.nan, 'A', np.nan, 4], | ||
[np.nan, 'C', np.nan, 6], | ||
[np.nan, 'B', np.nan, 5], | ||
['A', np.nan, 1, np.nan], | ||
['B', np.nan, 2, np.nan], | ||
['C', np.nan, 3, np.nan]] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Where are all the NaNs coming from? They don't seem to be there in the docstring example There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, I see, because here 'zoo' is used for index and not 'foo'. |
||
index = Index(data=['q', 't', 'w', 'x', 'y', 'z'], name='zoo') | ||
columns = MultiIndex(levels=[['bar', 'baz'], ['one', 'two']], | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add a test with a MultiIndex and pass values as a tuple There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are you looking for something like the following? (please correct me if I am wrong)
then pivot it:
so the output would be:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ping @jreback There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yep |
||
labels=[[0, 0, 1, 1], [0, 1, 0, 1]], | ||
names=[None, 'foo']) | ||
expected = DataFrame(data=data, index=index, | ||
columns=columns, dtype='object') | ||
tm.assert_frame_equal(result, expected) | ||
|
||
@pytest.mark.xfail(reason='MultiIndexed unstack with tuple names fails' | ||
'with KeyError #19966') | ||
def test_pivot_with_multiindex(self): | ||
# issue #17160 | ||
index = Index(data=[0, 1, 2, 3, 4, 5]) | ||
data = [['one', 'A', 1, 'x'], | ||
['one', 'B', 2, 'y'], | ||
['one', 'C', 3, 'z'], | ||
['two', 'A', 4, 'q'], | ||
['two', 'B', 5, 'w'], | ||
['two', 'C', 6, 't']] | ||
columns = MultiIndex(levels=[['bar', 'baz'], ['first', 'second']], | ||
labels=[[0, 0, 1, 1], [0, 1, 0, 1]]) | ||
df = DataFrame(data=data, index=index, columns=columns, dtype='object') | ||
result = df.pivot(index=('bar', 'first'), columns=('bar', 'second'), | ||
values=('baz', 'first')) | ||
|
||
data = {'A': Series([1, 4], index=['one', 'two']), | ||
'B': Series([2, 5], index=['one', 'two']), | ||
'C': Series([3, 6], index=['one', 'two'])} | ||
expected = DataFrame(data) | ||
tm.assert_frame_equal(result, expected) | ||
|
||
def test_pivot_with_tuple_of_values(self): | ||
# issue #17160 | ||
df = pd.DataFrame({'foo': ['one', 'one', 'one', 'two', 'two', 'two'], | ||
'bar': ['A', 'B', 'C', 'A', 'B', 'C'], | ||
'baz': [1, 2, 3, 4, 5, 6], | ||
'zoo': ['x', 'y', 'z', 'q', 'w', 't']}) | ||
with pytest.raises(KeyError): | ||
# tuple is seen as a single column name | ||
df.pivot(index='zoo', columns='foo', values=('bar', 'baz')) | ||
|
||
def test_margins(self): | ||
def _check_output(result, values_col, index=['A', 'B'], | ||
columns=['C'], | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you add a comment here on why excluding tuples