Skip to content

TST: split up pandas/tests/indexing/test_multiindex.py #23912

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

Merged
merged 22 commits into from
Nov 29, 2018
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
6d3592a
move file to subdirectory
simonjayhawkins Nov 25, 2018
cdc5f62
split off TestMultiIndexPanel class
simonjayhawkins Nov 25, 2018
55ef180
split off TestMultiIndexSlicers class
simonjayhawkins Nov 25, 2018
2002877
move iloc tests from TestMultiIndexBasic class
simonjayhawkins Nov 25, 2018
beafea9
move loc tests from TestMultiIndexBasic class
simonjayhawkins Nov 25, 2018
e921081
move datetime test
simonjayhawkins Nov 25, 2018
b730f16
move ix test
simonjayhawkins Nov 25, 2018
f0bffc6
move partial tests
simonjayhawkins Nov 25, 2018
fa44d52
move xs tests
simonjayhawkins Nov 25, 2018
5b50ab1
move sorted tests
simonjayhawkins Nov 25, 2018
b0a6d17
fix failing tests
simonjayhawkins Nov 25, 2018
f416034
move more tests to test_slice.py
simonjayhawkins Nov 27, 2018
c509d7f
move tests to test_set_ops.py
simonjayhawkins Nov 27, 2018
4da9174
Merge remote-tracking branch 'upstream/master' into split-mi-test
simonjayhawkins Nov 27, 2018
2bad48c
move test and fixture to test_loc.py
simonjayhawkins Nov 27, 2018
53b5a20
move tests to test_setitem.py
simonjayhawkins Nov 27, 2018
4ce1c8e
move tests to test_getitem.py
simonjayhawkins Nov 27, 2018
600925c
fix failing test
simonjayhawkins Nov 27, 2018
684e3c3
Merge remote-tracking branch 'upstream/master' into split-mi-test
simonjayhawkins Nov 27, 2018
8b016cc
Merge remote-tracking branch 'upstream/master' into split-mi-test
simonjayhawkins Nov 28, 2018
c07e324
Merge remote-tracking branch 'upstream/master' into split-mi-test
simonjayhawkins Nov 28, 2018
5869d15
Merge remote-tracking branch 'upstream/master' into split-mi-test
simonjayhawkins Nov 29, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file.
32 changes: 32 additions & 0 deletions pandas/tests/indexing/multiindex/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import numpy as np
import pytest

from pandas import DataFrame, Index, MultiIndex
from pandas.util import testing as tm


@pytest.fixture
def multiindex_dataframe_random_data():
"""DataFrame with 2 level MultiIndex with random data"""
index = MultiIndex(levels=[['foo', 'bar', 'baz', 'qux'], ['one', 'two',
'three']],
labels=[[0, 0, 0, 1, 1, 2, 2, 3, 3, 3],
[0, 1, 2, 0, 1, 1, 2, 0, 1, 2]],
names=['first', 'second'])
return DataFrame(np.random.randn(10, 3), index=index,
columns=Index(['A', 'B', 'C'], name='exp'))


@pytest.fixture
def multiindex_year_month_day_dataframe_random_data():
"""DataFrame with 3 level MultiIndex (year, month, day) covering
first 100 business days from 2000-01-01 with random data"""
tm.N = 100
tdf = tm.makeTimeDataFrame()
ymd = tdf.groupby([lambda x: x.year, lambda x: x.month,
lambda x: x.day]).sum()
# use Int64Index, to make sure things work
ymd.index.set_levels([lev.astype('i8') for lev in ymd.index.levels],
inplace=True)
ymd.index.set_names(['year', 'month', 'day'], inplace=True)
return ymd
22 changes: 22 additions & 0 deletions pandas/tests/indexing/multiindex/test_datetime.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from datetime import datetime

import numpy as np

from pandas import Index, Period, Series, period_range


def test_multiindex_period_datetime():
# GH4861, using datetime in period of multiindex raises exception

idx1 = Index(['a', 'a', 'a', 'b', 'b'])
idx2 = period_range('2012-01', periods=len(idx1), freq='M')
s = Series(np.random.randn(len(idx1)), [idx1, idx2])

# try Period as index
expected = s.iloc[0]
result = s.loc['a', Period('2012-01')]
assert result == expected

# try datetime as index
result = s.loc['a', datetime(2012, 1, 1)]
assert result == expected
129 changes: 129 additions & 0 deletions pandas/tests/indexing/multiindex/test_iloc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
from warnings import catch_warnings

import numpy as np
import pytest

from pandas import DataFrame, MultiIndex, Series
from pandas.util import testing as tm


@pytest.mark.filterwarnings("ignore:\\n.ix:DeprecationWarning")
class TestMultiIndexIloc(object):

def test_iloc_getitem_multiindex2(self):
# TODO(wesm): fix this
pytest.skip('this test was being suppressed, '
'needs to be fixed')

arr = np.random.randn(3, 3)
df = DataFrame(arr, columns=[[2, 2, 4], [6, 8, 10]],
index=[[4, 4, 8], [8, 10, 12]])

rs = df.iloc[2]
xp = Series(arr[2], index=df.columns)
tm.assert_series_equal(rs, xp)

rs = df.iloc[:, 2]
xp = Series(arr[:, 2], index=df.index)
tm.assert_series_equal(rs, xp)

rs = df.iloc[2, 2]
xp = df.values[2, 2]
assert rs == xp

# for multiple items
# GH 5528
rs = df.iloc[[0, 1]]
xp = df.xs(4, drop_level=False)
tm.assert_frame_equal(rs, xp)

tup = zip(*[['a', 'a', 'b', 'b'], ['x', 'y', 'x', 'y']])
index = MultiIndex.from_tuples(tup)
df = DataFrame(np.random.randn(4, 4), index=index)
rs = df.iloc[[2, 3]]
xp = df.xs('b', drop_level=False)
tm.assert_frame_equal(rs, xp)

def test_iloc_getitem_multiindex(self):
mi_labels = DataFrame(np.random.randn(4, 3),
columns=[['i', 'i', 'j'], ['A', 'A', 'B']],
index=[['i', 'i', 'j', 'k'],
['X', 'X', 'Y', 'Y']])

mi_int = DataFrame(np.random.randn(3, 3),
columns=[[2, 2, 4], [6, 8, 10]],
index=[[4, 4, 8], [8, 10, 12]])

# the first row
rs = mi_int.iloc[0]
with catch_warnings(record=True):
xp = mi_int.ix[4].ix[8]
tm.assert_series_equal(rs, xp, check_names=False)
assert rs.name == (4, 8)
assert xp.name == 8

# 2nd (last) columns
rs = mi_int.iloc[:, 2]
with catch_warnings(record=True):
xp = mi_int.ix[:, 2]
tm.assert_series_equal(rs, xp)

# corner column
rs = mi_int.iloc[2, 2]
with catch_warnings(record=True):
# First level is int - so use .loc rather than .ix (GH 21593)
xp = mi_int.loc[(8, 12), (4, 10)]
assert rs == xp

# this is basically regular indexing
rs = mi_labels.iloc[2, 2]
with catch_warnings(record=True):
xp = mi_labels.ix['j'].ix[:, 'j'].ix[0, 0]
assert rs == xp

def test_frame_getitem_setitem_slice(
self, multiindex_dataframe_random_data):
frame = multiindex_dataframe_random_data
# getitem
result = frame.iloc[:4]
expected = frame[:4]
tm.assert_frame_equal(result, expected)

# setitem
cp = frame.copy()
cp.iloc[:4] = 0

assert (cp.values[:4] == 0).all()
assert (cp.values[4:] != 0).all()

def test_indexing_ambiguity_bug_1678(self):
columns = MultiIndex.from_tuples([('Ohio', 'Green'), ('Ohio', 'Red'), (
'Colorado', 'Green')])
index = MultiIndex.from_tuples([('a', 1), ('a', 2), ('b', 1), ('b', 2)
])

frame = DataFrame(np.arange(12).reshape((4, 3)), index=index,
columns=columns)

result = frame.iloc[:, 1]
exp = frame.loc[:, ('Ohio', 'Red')]
assert isinstance(result, Series)
tm.assert_series_equal(result, exp)

def test_iloc_mi(self):
# GH 13797
# Test if iloc can handle integer locations in MultiIndexed DataFrame

data = [['str00', 'str01'], ['str10', 'str11'], ['str20', 'srt21'],
['str30', 'str31'], ['str40', 'str41']]

mi = MultiIndex.from_tuples(
[('CC', 'A'), ('CC', 'B'), ('CC', 'B'), ('BB', 'a'), ('BB', 'b')])

expected = DataFrame(data)
df_mi = DataFrame(data, index=mi)

result = DataFrame([[df_mi.iloc[r, c] for c in range(2)]
for r in range(5)])

tm.assert_frame_equal(result, expected)
27 changes: 27 additions & 0 deletions pandas/tests/indexing/multiindex/test_ix.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from warnings import catch_warnings, simplefilter

import pytest

from pandas.compat import lrange


@pytest.mark.filterwarnings("ignore:\\n.ix:DeprecationWarning")
class TestMultiIndexIx(object):

def test_frame_setitem_ix(self, multiindex_dataframe_random_data):
frame = multiindex_dataframe_random_data
frame.loc[('bar', 'two'), 'B'] = 5
assert frame.loc[('bar', 'two'), 'B'] == 5

# with integer labels
df = frame.copy()
df.columns = lrange(3)
df.loc[('bar', 'two'), 1] = 7
assert df.loc[('bar', 'two'), 1] == 7

with catch_warnings(record=True):
simplefilter("ignore", DeprecationWarning)
df = frame.copy()
df.columns = lrange(3)
df.ix[('bar', 'two'), 1] = 7
assert df.loc[('bar', 'two'), 1] == 7
163 changes: 163 additions & 0 deletions pandas/tests/indexing/multiindex/test_loc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
from warnings import catch_warnings

import numpy as np
import pytest

from pandas import DataFrame, MultiIndex, Series
from pandas.util import testing as tm


@pytest.mark.filterwarnings("ignore:\\n.ix:DeprecationWarning")
class TestMultiIndexLoc(object):

def test_loc_getitem_series(self):
# GH14730
# passing a series as a key with a MultiIndex
index = MultiIndex.from_product([[1, 2, 3], ['A', 'B', 'C']])
x = Series(index=index, data=range(9), dtype=np.float64)
y = Series([1, 3])
expected = Series(
data=[0, 1, 2, 6, 7, 8],
index=MultiIndex.from_product([[1, 3], ['A', 'B', 'C']]),
dtype=np.float64)
result = x.loc[y]
tm.assert_series_equal(result, expected)

result = x.loc[[1, 3]]
tm.assert_series_equal(result, expected)

# GH15424
y1 = Series([1, 3], index=[1, 2])
result = x.loc[y1]
tm.assert_series_equal(result, expected)

empty = Series(data=[], dtype=np.float64)
expected = Series([], index=MultiIndex(
levels=index.levels, labels=[[], []], dtype=np.float64))
result = x.loc[empty]
tm.assert_series_equal(result, expected)

def test_loc_getitem_array(self):
# GH15434
# passing an array as a key with a MultiIndex
index = MultiIndex.from_product([[1, 2, 3], ['A', 'B', 'C']])
x = Series(index=index, data=range(9), dtype=np.float64)
y = np.array([1, 3])
expected = Series(
data=[0, 1, 2, 6, 7, 8],
index=MultiIndex.from_product([[1, 3], ['A', 'B', 'C']]),
dtype=np.float64)
result = x.loc[y]
tm.assert_series_equal(result, expected)

# empty array:
empty = np.array([])
expected = Series([], index=MultiIndex(
levels=index.levels, labels=[[], []], dtype=np.float64))
result = x.loc[empty]
tm.assert_series_equal(result, expected)

# 0-dim array (scalar):
scalar = np.int64(1)
expected = Series(
data=[0, 1, 2],
index=['A', 'B', 'C'],
dtype=np.float64)
result = x.loc[scalar]
tm.assert_series_equal(result, expected)

def test_loc_multiindex(self):

mi_labels = DataFrame(np.random.randn(3, 3),
columns=[['i', 'i', 'j'], ['A', 'A', 'B']],
index=[['i', 'i', 'j'], ['X', 'X', 'Y']])

mi_int = DataFrame(np.random.randn(3, 3),
columns=[[2, 2, 4], [6, 8, 10]],
index=[[4, 4, 8], [8, 10, 12]])

# the first row
rs = mi_labels.loc['i']
with catch_warnings(record=True):
xp = mi_labels.ix['i']
tm.assert_frame_equal(rs, xp)

# 2nd (last) columns
rs = mi_labels.loc[:, 'j']
with catch_warnings(record=True):
xp = mi_labels.ix[:, 'j']
tm.assert_frame_equal(rs, xp)

# corner column
rs = mi_labels.loc['j'].loc[:, 'j']
with catch_warnings(record=True):
xp = mi_labels.ix['j'].ix[:, 'j']
tm.assert_frame_equal(rs, xp)

# with a tuple
rs = mi_labels.loc[('i', 'X')]
with catch_warnings(record=True):
xp = mi_labels.ix[('i', 'X')]
tm.assert_frame_equal(rs, xp)

rs = mi_int.loc[4]
with catch_warnings(record=True):
xp = mi_int.ix[4]
tm.assert_frame_equal(rs, xp)

# missing label
pytest.raises(KeyError, lambda: mi_int.loc[2])
with catch_warnings(record=True):
# GH 21593
pytest.raises(KeyError, lambda: mi_int.ix[2])

def test_loc_multiindex_indexer_none(self):

# GH6788
# multi-index indexer is None (meaning take all)
attributes = ['Attribute' + str(i) for i in range(1)]
attribute_values = ['Value' + str(i) for i in range(5)]

index = MultiIndex.from_product([attributes, attribute_values])
df = 0.1 * np.random.randn(10, 1 * 5) + 0.5
df = DataFrame(df, columns=index)
result = df[attributes]
tm.assert_frame_equal(result, df)

# GH 7349
# loc with a multi-index seems to be doing fallback
df = DataFrame(np.arange(12).reshape(-1, 1),
index=MultiIndex.from_product([[1, 2, 3, 4],
[1, 2, 3]]))

expected = df.loc[([1, 2], ), :]
result = df.loc[[1, 2]]
tm.assert_frame_equal(result, expected)

def test_loc_multiindex_incomplete(self):

# GH 7399
# incomplete indexers
s = Series(np.arange(15, dtype='int64'),
MultiIndex.from_product([range(5), ['a', 'b', 'c']]))
expected = s.loc[:, 'a':'c']

result = s.loc[0:4, 'a':'c']
tm.assert_series_equal(result, expected)
tm.assert_series_equal(result, expected)

result = s.loc[:4, 'a':'c']
tm.assert_series_equal(result, expected)
tm.assert_series_equal(result, expected)

result = s.loc[0:, 'a':'c']
tm.assert_series_equal(result, expected)
tm.assert_series_equal(result, expected)

# GH 7400
# multiindexer gettitem with list of indexers skips wrong element
s = Series(np.arange(15, dtype='int64'),
MultiIndex.from_product([range(5), ['a', 'b', 'c']]))
expected = s.iloc[[6, 7, 8, 12, 13, 14]]
result = s.loc[2:4:2, 'a':'c']
tm.assert_series_equal(result, expected)
Loading