123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416 |
- import numpy as np
- import pytest
- from pandas.compat import lrange
- import pandas as pd
- from pandas import DataFrame, Index, MultiIndex, Series, Timestamp, isna
- from pandas.util.testing import (
- assert_frame_equal, assert_produces_warning, assert_series_equal)
- def test_first_last_nth(df):
- # tests for first / last / nth
- grouped = df.groupby('A')
- first = grouped.first()
- expected = df.loc[[1, 0], ['B', 'C', 'D']]
- expected.index = Index(['bar', 'foo'], name='A')
- expected = expected.sort_index()
- assert_frame_equal(first, expected)
- nth = grouped.nth(0)
- assert_frame_equal(nth, expected)
- last = grouped.last()
- expected = df.loc[[5, 7], ['B', 'C', 'D']]
- expected.index = Index(['bar', 'foo'], name='A')
- assert_frame_equal(last, expected)
- nth = grouped.nth(-1)
- assert_frame_equal(nth, expected)
- nth = grouped.nth(1)
- expected = df.loc[[2, 3], ['B', 'C', 'D']].copy()
- expected.index = Index(['foo', 'bar'], name='A')
- expected = expected.sort_index()
- assert_frame_equal(nth, expected)
- # it works!
- grouped['B'].first()
- grouped['B'].last()
- grouped['B'].nth(0)
- df.loc[df['A'] == 'foo', 'B'] = np.nan
- assert isna(grouped['B'].first()['foo'])
- assert isna(grouped['B'].last()['foo'])
- assert isna(grouped['B'].nth(0)['foo'])
- # v0.14.0 whatsnew
- df = DataFrame([[1, np.nan], [1, 4], [5, 6]], columns=['A', 'B'])
- g = df.groupby('A')
- result = g.first()
- expected = df.iloc[[1, 2]].set_index('A')
- assert_frame_equal(result, expected)
- expected = df.iloc[[1, 2]].set_index('A')
- result = g.nth(0, dropna='any')
- assert_frame_equal(result, expected)
- def test_first_last_nth_dtypes(df_mixed_floats):
- df = df_mixed_floats.copy()
- df['E'] = True
- df['F'] = 1
- # tests for first / last / nth
- grouped = df.groupby('A')
- first = grouped.first()
- expected = df.loc[[1, 0], ['B', 'C', 'D', 'E', 'F']]
- expected.index = Index(['bar', 'foo'], name='A')
- expected = expected.sort_index()
- assert_frame_equal(first, expected)
- last = grouped.last()
- expected = df.loc[[5, 7], ['B', 'C', 'D', 'E', 'F']]
- expected.index = Index(['bar', 'foo'], name='A')
- expected = expected.sort_index()
- assert_frame_equal(last, expected)
- nth = grouped.nth(1)
- expected = df.loc[[3, 2], ['B', 'C', 'D', 'E', 'F']]
- expected.index = Index(['bar', 'foo'], name='A')
- expected = expected.sort_index()
- assert_frame_equal(nth, expected)
- # GH 2763, first/last shifting dtypes
- idx = lrange(10)
- idx.append(9)
- s = Series(data=lrange(11), index=idx, name='IntCol')
- assert s.dtype == 'int64'
- f = s.groupby(level=0).first()
- assert f.dtype == 'int64'
- def test_nth():
- df = DataFrame([[1, np.nan], [1, 4], [5, 6]], columns=['A', 'B'])
- g = df.groupby('A')
- assert_frame_equal(g.nth(0), df.iloc[[0, 2]].set_index('A'))
- assert_frame_equal(g.nth(1), df.iloc[[1]].set_index('A'))
- assert_frame_equal(g.nth(2), df.loc[[]].set_index('A'))
- assert_frame_equal(g.nth(-1), df.iloc[[1, 2]].set_index('A'))
- assert_frame_equal(g.nth(-2), df.iloc[[0]].set_index('A'))
- assert_frame_equal(g.nth(-3), df.loc[[]].set_index('A'))
- assert_series_equal(g.B.nth(0), df.set_index('A').B.iloc[[0, 2]])
- assert_series_equal(g.B.nth(1), df.set_index('A').B.iloc[[1]])
- assert_frame_equal(g[['B']].nth(0),
- df.loc[[0, 2], ['A', 'B']].set_index('A'))
- exp = df.set_index('A')
- assert_frame_equal(g.nth(0, dropna='any'), exp.iloc[[1, 2]])
- assert_frame_equal(g.nth(-1, dropna='any'), exp.iloc[[1, 2]])
- exp['B'] = np.nan
- assert_frame_equal(g.nth(7, dropna='any'), exp.iloc[[1, 2]])
- assert_frame_equal(g.nth(2, dropna='any'), exp.iloc[[1, 2]])
- # out of bounds, regression from 0.13.1
- # GH 6621
- df = DataFrame({'color': {0: 'green',
- 1: 'green',
- 2: 'red',
- 3: 'red',
- 4: 'red'},
- 'food': {0: 'ham',
- 1: 'eggs',
- 2: 'eggs',
- 3: 'ham',
- 4: 'pork'},
- 'two': {0: 1.5456590000000001,
- 1: -0.070345000000000005,
- 2: -2.4004539999999999,
- 3: 0.46206000000000003,
- 4: 0.52350799999999997},
- 'one': {0: 0.56573799999999996,
- 1: -0.9742360000000001,
- 2: 1.033801,
- 3: -0.78543499999999999,
- 4: 0.70422799999999997}}).set_index(['color',
- 'food'])
- result = df.groupby(level=0, as_index=False).nth(2)
- expected = df.iloc[[-1]]
- assert_frame_equal(result, expected)
- result = df.groupby(level=0, as_index=False).nth(3)
- expected = df.loc[[]]
- assert_frame_equal(result, expected)
- # GH 7559
- # from the vbench
- df = DataFrame(np.random.randint(1, 10, (100, 2)), dtype='int64')
- s = df[1]
- g = df[0]
- expected = s.groupby(g).first()
- expected2 = s.groupby(g).apply(lambda x: x.iloc[0])
- assert_series_equal(expected2, expected, check_names=False)
- assert expected.name == 1
- assert expected2.name == 1
- # validate first
- v = s[g == 1].iloc[0]
- assert expected.iloc[0] == v
- assert expected2.iloc[0] == v
- # this is NOT the same as .first (as sorted is default!)
- # as it keeps the order in the series (and not the group order)
- # related GH 7287
- expected = s.groupby(g, sort=False).first()
- result = s.groupby(g, sort=False).nth(0, dropna='all')
- assert_series_equal(result, expected)
- # doc example
- df = DataFrame([[1, np.nan], [1, 4], [5, 6]], columns=['A', 'B'])
- g = df.groupby('A')
- # PR 17493, related to issue 11038
- # test Series.nth with True for dropna produces FutureWarning
- with assert_produces_warning(FutureWarning):
- result = g.B.nth(0, dropna=True)
- expected = g.B.first()
- assert_series_equal(result, expected)
- # test multiple nth values
- df = DataFrame([[1, np.nan], [1, 3], [1, 4], [5, 6], [5, 7]],
- columns=['A', 'B'])
- g = df.groupby('A')
- assert_frame_equal(g.nth(0), df.iloc[[0, 3]].set_index('A'))
- assert_frame_equal(g.nth([0]), df.iloc[[0, 3]].set_index('A'))
- assert_frame_equal(g.nth([0, 1]), df.iloc[[0, 1, 3, 4]].set_index('A'))
- assert_frame_equal(
- g.nth([0, -1]), df.iloc[[0, 2, 3, 4]].set_index('A'))
- assert_frame_equal(
- g.nth([0, 1, 2]), df.iloc[[0, 1, 2, 3, 4]].set_index('A'))
- assert_frame_equal(
- g.nth([0, 1, -1]), df.iloc[[0, 1, 2, 3, 4]].set_index('A'))
- assert_frame_equal(g.nth([2]), df.iloc[[2]].set_index('A'))
- assert_frame_equal(g.nth([3, 4]), df.loc[[]].set_index('A'))
- business_dates = pd.date_range(start='4/1/2014', end='6/30/2014',
- freq='B')
- df = DataFrame(1, index=business_dates, columns=['a', 'b'])
- # get the first, fourth and last two business days for each month
- key = [df.index.year, df.index.month]
- result = df.groupby(key, as_index=False).nth([0, 3, -2, -1])
- expected_dates = pd.to_datetime(
- ['2014/4/1', '2014/4/4', '2014/4/29', '2014/4/30', '2014/5/1',
- '2014/5/6', '2014/5/29', '2014/5/30', '2014/6/2', '2014/6/5',
- '2014/6/27', '2014/6/30'])
- expected = DataFrame(1, columns=['a', 'b'], index=expected_dates)
- assert_frame_equal(result, expected)
- def test_nth_multi_index(three_group):
- # PR 9090, related to issue 8979
- # test nth on MultiIndex, should match .first()
- grouped = three_group.groupby(['A', 'B'])
- result = grouped.nth(0)
- expected = grouped.first()
- assert_frame_equal(result, expected)
- @pytest.mark.parametrize('data, expected_first, expected_last', [
- ({'id': ['A'],
- 'time': Timestamp('2012-02-01 14:00:00',
- tz='US/Central'),
- 'foo': [1]},
- {'id': ['A'],
- 'time': Timestamp('2012-02-01 14:00:00',
- tz='US/Central'),
- 'foo': [1]},
- {'id': ['A'],
- 'time': Timestamp('2012-02-01 14:00:00',
- tz='US/Central'),
- 'foo': [1]}),
- ({'id': ['A', 'B', 'A'],
- 'time': [Timestamp('2012-01-01 13:00:00',
- tz='America/New_York'),
- Timestamp('2012-02-01 14:00:00',
- tz='US/Central'),
- Timestamp('2012-03-01 12:00:00',
- tz='Europe/London')],
- 'foo': [1, 2, 3]},
- {'id': ['A', 'B'],
- 'time': [Timestamp('2012-01-01 13:00:00',
- tz='America/New_York'),
- Timestamp('2012-02-01 14:00:00',
- tz='US/Central')],
- 'foo': [1, 2]},
- {'id': ['A', 'B'],
- 'time': [Timestamp('2012-03-01 12:00:00',
- tz='Europe/London'),
- Timestamp('2012-02-01 14:00:00',
- tz='US/Central')],
- 'foo': [3, 2]})
- ])
- def test_first_last_tz(data, expected_first, expected_last):
- # GH15884
- # Test that the timezone is retained when calling first
- # or last on groupby with as_index=False
- df = DataFrame(data)
- result = df.groupby('id', as_index=False).first()
- expected = DataFrame(expected_first)
- cols = ['id', 'time', 'foo']
- assert_frame_equal(result[cols], expected[cols])
- result = df.groupby('id', as_index=False)['time'].first()
- assert_frame_equal(result, expected[['id', 'time']])
- result = df.groupby('id', as_index=False).last()
- expected = DataFrame(expected_last)
- cols = ['id', 'time', 'foo']
- assert_frame_equal(result[cols], expected[cols])
- result = df.groupby('id', as_index=False)['time'].last()
- assert_frame_equal(result, expected[['id', 'time']])
- def test_nth_multi_index_as_expected():
- # PR 9090, related to issue 8979
- # test nth on MultiIndex
- three_group = DataFrame(
- {'A': ['foo', 'foo', 'foo', 'foo', 'bar', 'bar', 'bar', 'bar',
- 'foo', 'foo', 'foo'],
- 'B': ['one', 'one', 'one', 'two', 'one', 'one', 'one', 'two',
- 'two', 'two', 'one'],
- 'C': ['dull', 'dull', 'shiny', 'dull', 'dull', 'shiny', 'shiny',
- 'dull', 'shiny', 'shiny', 'shiny']})
- grouped = three_group.groupby(['A', 'B'])
- result = grouped.nth(0)
- expected = DataFrame(
- {'C': ['dull', 'dull', 'dull', 'dull']},
- index=MultiIndex.from_arrays([['bar', 'bar', 'foo', 'foo'],
- ['one', 'two', 'one', 'two']],
- names=['A', 'B']))
- assert_frame_equal(result, expected)
- def test_groupby_head_tail():
- df = DataFrame([[1, 2], [1, 4], [5, 6]], columns=['A', 'B'])
- g_as = df.groupby('A', as_index=True)
- g_not_as = df.groupby('A', as_index=False)
- # as_index= False, much easier
- assert_frame_equal(df.loc[[0, 2]], g_not_as.head(1))
- assert_frame_equal(df.loc[[1, 2]], g_not_as.tail(1))
- empty_not_as = DataFrame(columns=df.columns,
- index=pd.Index([], dtype=df.index.dtype))
- empty_not_as['A'] = empty_not_as['A'].astype(df.A.dtype)
- empty_not_as['B'] = empty_not_as['B'].astype(df.B.dtype)
- assert_frame_equal(empty_not_as, g_not_as.head(0))
- assert_frame_equal(empty_not_as, g_not_as.tail(0))
- assert_frame_equal(empty_not_as, g_not_as.head(-1))
- assert_frame_equal(empty_not_as, g_not_as.tail(-1))
- assert_frame_equal(df, g_not_as.head(7)) # contains all
- assert_frame_equal(df, g_not_as.tail(7))
- # as_index=True, (used to be different)
- df_as = df
- assert_frame_equal(df_as.loc[[0, 2]], g_as.head(1))
- assert_frame_equal(df_as.loc[[1, 2]], g_as.tail(1))
- empty_as = DataFrame(index=df_as.index[:0], columns=df.columns)
- empty_as['A'] = empty_not_as['A'].astype(df.A.dtype)
- empty_as['B'] = empty_not_as['B'].astype(df.B.dtype)
- assert_frame_equal(empty_as, g_as.head(0))
- assert_frame_equal(empty_as, g_as.tail(0))
- assert_frame_equal(empty_as, g_as.head(-1))
- assert_frame_equal(empty_as, g_as.tail(-1))
- assert_frame_equal(df_as, g_as.head(7)) # contains all
- assert_frame_equal(df_as, g_as.tail(7))
- # test with selection
- assert_frame_equal(g_as[[]].head(1), df_as.loc[[0, 2], []])
- assert_frame_equal(g_as[['A']].head(1), df_as.loc[[0, 2], ['A']])
- assert_frame_equal(g_as[['B']].head(1), df_as.loc[[0, 2], ['B']])
- assert_frame_equal(g_as[['A', 'B']].head(1), df_as.loc[[0, 2]])
- assert_frame_equal(g_not_as[[]].head(1), df_as.loc[[0, 2], []])
- assert_frame_equal(g_not_as[['A']].head(1), df_as.loc[[0, 2], ['A']])
- assert_frame_equal(g_not_as[['B']].head(1), df_as.loc[[0, 2], ['B']])
- assert_frame_equal(g_not_as[['A', 'B']].head(1), df_as.loc[[0, 2]])
- def test_group_selection_cache():
- # GH 12839 nth, head, and tail should return same result consistently
- df = DataFrame([[1, 2], [1, 4], [5, 6]], columns=['A', 'B'])
- expected = df.iloc[[0, 2]].set_index('A')
- g = df.groupby('A')
- result1 = g.head(n=2)
- result2 = g.nth(0)
- assert_frame_equal(result1, df)
- assert_frame_equal(result2, expected)
- g = df.groupby('A')
- result1 = g.tail(n=2)
- result2 = g.nth(0)
- assert_frame_equal(result1, df)
- assert_frame_equal(result2, expected)
- g = df.groupby('A')
- result1 = g.nth(0)
- result2 = g.head(n=2)
- assert_frame_equal(result1, expected)
- assert_frame_equal(result2, df)
- g = df.groupby('A')
- result1 = g.nth(0)
- result2 = g.tail(n=2)
- assert_frame_equal(result1, expected)
- assert_frame_equal(result2, df)
- def test_nth_empty():
- # GH 16064
- df = DataFrame(index=[0], columns=['a', 'b', 'c'])
- result = df.groupby('a').nth(10)
- expected = DataFrame(index=Index([], name='a'), columns=['b', 'c'])
- assert_frame_equal(result, expected)
- result = df.groupby(['a', 'b']).nth(10)
- expected = DataFrame(index=MultiIndex([[], []], [[], []],
- names=['a', 'b']),
- columns=['c'])
- assert_frame_equal(result, expected)
- def test_nth_column_order():
- # GH 20760
- # Check that nth preserves column order
- df = DataFrame([[1, 'b', 100],
- [1, 'a', 50],
- [1, 'a', np.nan],
- [2, 'c', 200],
- [2, 'd', 150]],
- columns=['A', 'C', 'B'])
- result = df.groupby('A').nth(0)
- expected = DataFrame([['b', 100.0],
- ['c', 200.0]],
- columns=['C', 'B'],
- index=Index([1, 2], name='A'))
- assert_frame_equal(result, expected)
- result = df.groupby('A').nth(-1, dropna='any')
- expected = DataFrame([['a', 50.0],
- ['d', 150.0]],
- columns=['C', 'B'],
- index=Index([1, 2], name='A'))
- assert_frame_equal(result, expected)
|