10000 split up pandas/tests/indexes/test_multi.py #18644 by elmq0022 · Pull Request #21514 · pandas-dev/pandas · GitHub
[go: up one dir, main page]

Skip to content

split up pandas/tests/indexes/test_multi.py #18644 #21514

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 7 commits into from
Jul 3, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
Prev Previous commit
split test_multi.py into separate files and address the comments from…
… pull request
  • Loading branch information
elmq0022 committed Jul 3, 2018
commit baaace366e15a770f69fff9a0ba82015309285c9
10 changes: 8 additions & 2 deletions pandas/tests/indexes/multi/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

@pytest.fixture
def idx():
# a MultiIndex used to test the general functionality of the
# general functionality of this object
major_axis = Index(['foo', 'bar', 'baz', 'qux'])
Copy link
Contributor

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 describing the fixture (always do this for fixtures)

minor_axis = Index(['one', 'two'])

Expand All @@ -24,14 +26,18 @@ def idx():

@pytest.fixture
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that you are iterating over this in a number of tests. why is that?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's more or less a holdover from how the inherited base test class was implemented. I was thinking I'd leave it in case anyone wanted to extend some of these cases with another test multi-index, but yes it looks kind of sloppy. I'll refactor it and remove the duplicate fixture.

Copy link
Contributor Author
@elmq0022 elmq0022 Jun 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, done with that, but some tests are not relevant to the MultiIndex class or will need to be refactored. I marked those tests with a TODO. The tests that I could refactor have been. 😅

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep that's ok. i expect after your refactor will need to go over this again and clean a bit

def index_names():
# names that match those in the idx fixture for testing equality of
# names assigned to the idx
return ['first', 'second']


@pytest.fixture
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok w/o using these a leading _ (e.g. holder) is ok

def _holder():
def holder():
# the MultiIndex constructor used to base compatibility with pickle
return MultiIndex


@pytest.fixture
def _compat_props():
def compat_props():
# a MultiIndex must have these properties associated with it
return ['shape', 'ndim', 'size']
8 changes: 8 additions & 0 deletions pandas/tests/indexes/multi/test_analytics.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import pytest


def test_shift(idx):

# GH8083 test the base class for shift
pytest.raises(NotImplementedError, idx.shift, 1)
pytest.raises(NotImplementedError, idx.shift, 1, 2)
25 changes: 9 additions & 16 deletions pandas/tests/indexes/multi/test_compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,8 @@ def test_logical_compat(idx):

def test_boolean_context_compat(idx):

# boolean context compat
def f():
if idx:
pass

tm.assert_raises_regex(ValueError, 'The truth value of a', f)
with pytest.raises(ValueError):
bool(idx)


def test_boolean_context_compat2():
Expand All @@ -50,11 +46,8 @@ def test_boolean_context_compat2():
i2 = MultiIndex.from_tuples([('A', 1), ('A', 3)])
common = i1.intersection(i2)

def f():
if common:
pass

tm.assert_raises_regex(ValueError, 'The truth value of a', f)
with pytest.raises(ValueError):
bool(common)


def test_inplace_mutation_resets_values():
Expand Down Expand Up @@ -103,12 +96,12 @@ def test_inplace_mutation_resets_values():
tm.assert_almost_equal(mi2.values, new_values)


def test_ndarray_compat_properties(idx, _compat_props):
def test_ndarray_compat_properties(idx, compat_props):
assert idx.T.equals(idx)
assert idx.transpose().equals(idx)

values = idx.values
for prop in _compat_props:
for prop in compat_props:
assert getattr(idx, prop) == getattr(values, prop)

# test for validity
Expand All @@ -120,10 +113,10 @@ def test_compat(indices):
assert indices.tolist() == list(indices)


def test_pickle_compat_construction(_holder):
def test_pickle_compat_construction(holder):
# this is testing for pickle compat
if _holder is None:
if holder is None:
return

# need an object to create with
pytest.raises(TypeError, _holder)
pytest.raises(TypeError, holder)
78 changes: 1 addition & 77 deletions pandas/tests/indexes/multi/test_constructor.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import pandas as pd
import pandas.util.testing as tm
import pytest
from pandas import DataFrame, Index, MultiIndex, date_range
from pandas import Index, MultiIndex, date_range
from pandas._libs.tslib import Timestamp
from pandas.compat import lrange, range
from pandas.core.dtypes.cast import construct_1d_object_array_from_listlike
Expand Down Expand Up @@ -91,82 +91,6 @@ def test_copy_in_constructor():
assert mi.levels[0][0] == val


def test_reconstruct_sort():

# starts off lexsorted & monotonic
mi = MultiIndex.from_arrays([
['A', 'A', 'B', 'B', 'B'], [1, 2, 1, 2, 3]
])
assert mi.is_lexsorted()
assert mi.is_monotonic

recons = mi._sort_levels_monotonic()
assert recons.is_lexsorted()
assert recons.is_monotonic
assert mi is recons

assert mi.equals(recons)
assert Index(mi.values).equals(Index(recons.values))

# cannot convert to lexsorted
mi = pd.MultiIndex.from_tuples([('z', 'a'), ('x', 'a'), ('y', 'b'),
('x', 'b'), ('y', 'a'), ('z', 'b')],
names=['one', 'two'])
assert not mi.is_lexsorted()
assert not mi.is_monotonic

recons = mi._sort_levels_monotonic()
assert not recons.is_lexsorted()
assert not recons.is_monotonic

assert mi.equals(recons)
assert Index(mi.values).equals(Index(recons.values))

# cannot convert to lexsorted
mi = MultiIndex(levels=[['b', 'd', 'a'], [1, 2, 3]],
labels=[[0, 1, 0, 2], [2, 0, 0, 1]],
names=['col1', 'col2'])
assert not mi.is_lexsorted()
assert not mi.is_monotonic

recons = mi._sort_levels_monotonic()
assert not recons.is_lexsorted()
assert not recons.is_monotonic

assert mi.equals(recons)
assert Index(mi.values).equals(Index(recons.values))


def test_reconstruct_remove_unused():
# xref to GH 2770
df = DataFrame([['deleteMe', 1, 9],
['keepMe', 2, 9],
['keepMeToo', 3, 9]],
columns=['first', 'second', 'third'])
df2 = df.set_index(['first', 'second'], drop=False)
df2 = df2[df2['first'] != 'deleteMe']

# removed levels are there
expected = MultiIndex(levels=[['deleteMe', 'keepMe', 'keepMeToo'],
[1, 2, 3]],
labels=[[1, 2], [1, 2]],
names=['first', 'second'])
result = df2.index
tm.assert_index_equal(result, expected)

expected = MultiIndex(levels=[['keepMe', 'keepMeToo'],
[2, 3]],
labels=[[0, 1], [0, 1]],
names=['first', 'second'])
result = df2.index.remove_unused_levels()
tm.assert_index_equal(result, expected)

# idempotent
result2 = result.remove_unused_levels()
tm.assert_index_equal(result2, expected)
assert result2.is_(result)


def test_from_arrays(idx):
arrays = []
for lev, lab in zip(idx.levels, idx.labels):
Expand Down
36 changes: 0 additions & 36 deletions pandas/tests/indexes/multi/test_contains.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,39 +91,3 @@ def test_isin_level_kwarg():
tm.assert_numpy_array_equal(expected, idx.isin(vals_1, level='B'))

pytest.raises(KeyError, idx.isin, vals_1, level='C')


def test_hasnans_isnans(idx):
# GH 11343, added tests for hasnans / isnans
# TODO: remove or change test not valid for MultiIndex
if isinstance(idx, MultiIndex):
pass
# else:
# _index = idx.copy()

# # cases in indices doesn't include NaN
# expected = np.array([False] * len(_index), dtype=bool)
# tm.assert_numpy_array_equal(_index._isnan, expected)
# assert not _index.hasnans

# _index = idx.copy()
# values = _index.values

# if len(idx) == 0:
# continue
# elif isinstance(idx, DatetimeIndexOpsMixin):
# values[1] = iNaT
# elif isinstance(idx, (Int64Index, UInt64Index)):
# continue
# else:
# values[1] = np.nan

# if isinstance(idx, PeriodIndex):
# _index = idx.__class__(values, freq=idx.freq)
# else:
# _index = idx.__class__(values)

# expected = np.array([False] * len(_index), dtype=bool)
# expected[1] = True
# tm.assert_numpy_array_equal(_index._isnan, expected)
# assert _index.hasnans
40 changes: 33 additions & 7 deletions pandas/tests/indexes/multi/test_conversion.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,10 @@ def test_to_hierarchical():
assert result.names == index.names


def test_legacy_pickle():
if PY3:
pytest.skip("testing for legacy pickles not "
"support on py3")
@pytest.mark.skipif(PY3, reason="testing legacy pickles not support on py3")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is an open issue to blow these legacy pickles away

def test_legacy_pickle(datapath):

path = tm.get_data_path('multiindex_v1.pickle')
path = datapath('indexes', 'multi', 'data', 'multiindex_v1.pickle')
obj = pd.read_pickle(path)

obj2 = MultiIndex.from_tuples(obj.values)
Expand All @@ -109,10 +107,10 @@ def test_legacy_pickle():
assert_almost_equal(exp, exp2)


def test_legacy_v2_unpickle():
def test_legacy_v2_unpickle(datapath):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same


# 0.7.3 -> 0.8.0 format manage
path = tm.get_data_path('mindex_073.pickle')
path = datapath('indexes', 'multi', 'data', 'mindex_073.pickle')
obj = pd.read_pickle(path)

obj2 = MultiIndex.from_tuples(obj.values)
Expand Down Expand Up @@ -148,3 +146,31 @@ def test_pickle(indices):
unpickled = tm.round_trip_pickle(indices)
assert indices.equals(unpickled)
indices.name = original_name


def test_to_series(idx):
# assert that we are creating a copy of the index

s = idx.to_series()
assert s.values is not idx.values
assert s.index is not idx
assert s.name == idx.name


def test_to_series_with_arguments(idx):
# GH18699

# index kwarg
s = idx.to_series(index=idx)

assert s.values is not idx.values
assert s.index is idx
assert s.name == idx.name

# name kwarg
idx = idx
s = idx.to_series(name='__test')

assert s.values is not idx.values
assert s.index is not idx
assert s.name != idx.name
2 changes: 1 addition & 1 deletion pandas/tests/indexes/multi/test_copy.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-

from copy import copy, deepcopy

import pandas.util.testing as tm
from pandas import (CategoricalIndex, IntervalIndex, MultiIndex, PeriodIndex,
Expand Down Expand Up @@ -111,7 +112,6 @@ def test_ensure_copied_data(idx):


def test_copy_and_deepcopy(indices):
from copy import copy, deepcopy

if isinstance(indices, MultiIndex):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

parameterize and don't need the fixure (it can just be a MI)

return
Expand Down
22 changes: 0 additions & 22 deletions pandas/tests/indexes/multi/test_drop.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,25 +124,3 @@ def test_drop_not_lexsorted():
with tm.assert_produces_warning(PerformanceWarning):
tm.assert_index_equal(lexsorted_mi.drop('a'),
not_lexsorted_mi.drop('a'))


def test_dropna():
# GH 6194
idx = pd.MultiIndex.from_arrays([[1, np.nan, 3, np.nan, 5],
[1, 2, np.nan, np.nan, 5],
['a', 'b', 'c', np.nan, 'e']])

exp = pd.MultiIndex.from_arrays([[1, 5],
[1, 5],
['a', 'e']])
tm.assert_index_equal(idx.dropna(), exp)
tm.assert_index_equal(idx.dropna(how='any'), exp)

exp = pd.MultiIndex.from_arrays([[1, np.nan, 3, 5],
[1, 2, np.nan, 5],
['a', 'b', 'c', 'e']])
tm.assert_index_equal(idx.dropna(how='all'), exp)

msg = "invalid how option: xxx"
with tm.assert_raises_regex(ValueError, msg):
idx.dropna(how='xxx')
38 changes: 4 additions & 34 deletions pandas/tests/indexes/multi/test_equivalence.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
import numpy as np
import pandas as pd
import pandas.util.testing as tm
from pandas import (Index, MultiIndex, PeriodIndex, RangeIndex, Series, compat,
isna)
from pandas import Index, MultiIndex, RangeIndex, Series, compat
from pandas.compat import lrange, lzip, range


Expand Down Expand Up @@ -33,8 +32,6 @@ def test_equals(idx):
def test_equals_op(idx):
# GH9947, GH10637
index_a = idx
if isinstance(index_a, PeriodIndex):
return

n = len(index_a)
index_b = index_a[0:-1]
Expand Down Expand Up @@ -208,37 +205,10 @@ def test_is_numeric(idx):
assert not idx.is_numeric()


def test_nulls(idx):
# this is really a smoke test for the methods
# as these are adequately tested for function elsewhere

# TODO: Remove or Refactor. MultiIndex not Implemeted.
for name, index in [('idx', idx), ]:
if len(index) == 0:
tm.assert_numpy_array_equal(
index.isna(), np.array([], dtype=bool))
elif isinstance(index, MultiIndex):
idx = index.copy()
msg = "isna is not defined for MultiIndex"
with tm.assert_raises_regex(NotImplementedError, msg):
idx.isna()
else:

if not index.hasnans:
tm.assert_numpy_array_equal(
index.isna(), np.zeros(len(index), dtype=bool))
tm.assert_numpy_array_equal(
index.notna(), np.ones(len(index), dtype=bool))
else:
result = isna(index)
tm.assert_numpy_array_equal(index.isna(), result)
tm.assert_numpy_array_equal(index.notna(), ~result)


def test_multiindex_compare():
# GH 21149
# Ensure comparison operations for MultiIndex with nlevels == 1
# behave consistently with those for MultiIndex with nlevels > 1
# GH 21149
# Ensure comparison operations for MultiIndex with nlevels == 1
# behave consistently with those for MultiIndex with nlevels > 1

midx = pd.MultiIndex.from_product([[0, 1]])

Expand Down
Loading
0