import numpy as np import pytest from pandas import DataFrame, MultiIndex, Series from pandas.util import testing as tm @pytest.fixture def simple_multiindex_dataframe(): """ Factory function to create simple 3 x 3 dataframe with both columns and row MultiIndex using supplied data or random data by default. """ def _simple_multiindex_dataframe(data=None): if data is None: data = np.random.randn(3, 3) return DataFrame(data, columns=[[2, 2, 4], [6, 8, 10]], index=[[4, 4, 8], [8, 10, 12]]) return _simple_multiindex_dataframe @pytest.mark.parametrize('indexer, expected', [ (lambda df: df.iloc[0], lambda arr: Series(arr[0], index=[[2, 2, 4], [6, 8, 10]], name=(4, 8))), (lambda df: df.iloc[2], lambda arr: Series(arr[2], index=[[2, 2, 4], [6, 8, 10]], name=(8, 12))), (lambda df: df.iloc[:, 2], lambda arr: Series( arr[:, 2], index=[[4, 4, 8], [8, 10, 12]], name=(4, 10))) ]) def test_iloc_returns_series(indexer, expected, simple_multiindex_dataframe): arr = np.random.randn(3, 3) df = simple_multiindex_dataframe(arr) result = indexer(df) expected = expected(arr) tm.assert_series_equal(result, expected) def test_iloc_returns_dataframe(simple_multiindex_dataframe): df = simple_multiindex_dataframe() result = df.iloc[[0, 1]] expected = df.xs(4, drop_level=False) tm.assert_frame_equal(result, expected) def test_iloc_returns_scalar(simple_multiindex_dataframe): arr = np.random.randn(3, 3) df = simple_multiindex_dataframe(arr) result = df.iloc[2, 2] expected = arr[2, 2] assert result == expected def test_iloc_getitem_multiple_items(): # GH 5528 tup = zip(*[['a', 'a', 'b', 'b'], ['x', 'y', 'x', 'y']]) index = MultiIndex.from_tuples(tup) df = DataFrame(np.random.randn(4, 4), index=index) result = df.iloc[[2, 3]] expected = df.xs('b', drop_level=False) tm.assert_frame_equal(result, expected) def test_iloc_getitem_labels(): # this is basically regular indexing arr = np.random.randn(4, 3) df = DataFrame(arr, columns=[['i', 'i', 'j'], ['A', 'A', 'B']], index=[['i', 'i', 'j', 'k'], ['X', 'X', 'Y', 'Y']]) result = df.iloc[2, 2] expected = arr[2, 2] assert result == expected def test_frame_getitem_slice(multiindex_dataframe_random_data): df = multiindex_dataframe_random_data result = df.iloc[:4] expected = df[:4] tm.assert_frame_equal(result, expected) def test_frame_setitem_slice(multiindex_dataframe_random_data): df = multiindex_dataframe_random_data df.iloc[:4] = 0 assert (df.values[:4] == 0).all() assert (df.values[4:] != 0).all() def test_indexing_ambiguity_bug_1678(): # GH 1678 columns = MultiIndex.from_tuples( [('Ohio', 'Green'), ('Ohio', 'Red'), ('Colorado', 'Green')]) index = MultiIndex.from_tuples([('a', 1), ('a', 2), ('b', 1), ('b', 2)]) df = DataFrame(np.arange(12).reshape((4, 3)), index=index, columns=columns) result = df.iloc[:, 1] expected = df.loc[:, ('Ohio', 'Red')] tm.assert_series_equal(result, expected) def test_iloc_integer_locations(): # GH 13797 data = [['str00', 'str01'], ['str10', 'str11'], ['str20', 'srt21'], ['str30', 'str31'], ['str40', 'str41']] index = MultiIndex.from_tuples( [('CC', 'A'), ('CC', 'B'), ('CC', 'B'), ('BB', 'a'), ('BB', 'b')]) expected = DataFrame(data) df = DataFrame(data, index=index) result = DataFrame([[df.iloc[r, c] for c in range(2)] for r in range(5)]) tm.assert_frame_equal(result, expected) @pytest.mark.parametrize( 'data, indexes, values, expected_k', [ # test without indexer value in first level of MultiIndex ([[2, 22, 5], [2, 33, 6]], [0, -1, 1], [2, 3, 1], [7, 10]), # test like code sample 1 in the issue ([[1, 22, 555], [1, 33, 666]], [0, -1, 1], [200, 300, 100], [755, 1066]), # test like code sample 2 in the issue ([[1, 3, 7], [2, 4, 8]], [0, -1, 1], [10, 10, 1000], [17, 1018]), # test like code sample 3 in the issue ([[1, 11, 4], [2, 22, 5], [3, 33, 6]], [0, -1, 1], [4, 7, 10], [8, 15, 13]) ]) def test_iloc_setitem_int_multiindex_series(data, indexes, values, expected_k): # GH17148 df = DataFrame(data=data, columns=['i', 'j', 'k']) df = df.set_index(['i', 'j']) series = df.k.copy() for i, v in zip(indexes, values): series.iloc[i] += v df['k'] = expected_k expected = df.k tm.assert_series_equal(series, expected) def test_getitem_iloc(multiindex_dataframe_random_data): df = multiindex_dataframe_random_data result = df.iloc[2] expected = df.xs(df.index[2]) tm.assert_series_equal(result, expected)