Skip to content

Commit f9dc98b

Browse files
lukemanleycodamuse
authored andcommitted
TST: MultiIndex.get_indexer with na/missing (pandas-dev#48877)
1 parent 5a0fa14 commit f9dc98b

File tree

7 files changed

+86
-2
lines changed

7 files changed

+86
-2
lines changed

doc/source/whatsnew/v2.0.0.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -607,7 +607,7 @@ Missing
607607

608608
MultiIndex
609609
^^^^^^^^^^
610-
- Bug in :meth:`MultiIndex.get_indexer` not matching ``NaN`` values (:issue:`37222`)
610+
- Bug in :meth:`MultiIndex.get_indexer` not matching ``NaN`` values (:issue:`29252`, :issue:`37222`, :issue:`38623`, :issue:`42883`, :issue:`43222`, :issue:`46173`, :issue:`48905`)
611611
- Bug in :meth:`MultiIndex.argsort` raising ``TypeError`` when index contains :attr:`NA` (:issue:`48495`)
612612
- Bug in :meth:`MultiIndex.difference` losing extension array dtype (:issue:`48606`)
613613
- Bug in :class:`MultiIndex.set_levels` raising ``IndexError`` when setting empty level (:issue:`48636`)

pandas/tests/indexes/multi/test_indexing.py

+14
Original file line numberDiff line numberDiff line change
@@ -933,3 +933,17 @@ def test_get_locs_reordering(keys, expected):
933933
result = idx.get_locs(keys)
934934
expected = np.array(expected, dtype=np.intp)
935935
tm.assert_numpy_array_equal(result, expected)
936+
937+
938+
def test_get_indexer_for_multiindex_with_nans(nulls_fixture):
939+
# GH37222
940+
idx1 = MultiIndex.from_product([["A"], [1.0, 2.0]], names=["id1", "id2"])
941+
idx2 = MultiIndex.from_product([["A"], [nulls_fixture, 2.0]], names=["id1", "id2"])
942+
943+
result = idx2.get_indexer(idx1)
944+
expected = np.array([-1, 1], dtype=np.intp)
945+
tm.assert_numpy_array_equal(result, expected)
946+
947+
result = idx1.get_indexer(idx2)
948+
expected = np.array([-1, 1], dtype=np.intp)
949+
tm.assert_numpy_array_equal(result, expected)

pandas/tests/indexes/multi/test_isin.py

+9
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,15 @@ def test_isin_nan():
1313
)
1414

1515

16+
def test_isin_missing(nulls_fixture):
17+
# GH48905
18+
mi1 = MultiIndex.from_tuples([(1, nulls_fixture)])
19+
mi2 = MultiIndex.from_tuples([(1, 1), (1, 2)])
20+
result = mi2.isin(mi1)
21+
expected = np.array([False, False])
22+
tm.assert_numpy_array_equal(result, expected)
23+
24+
1625
def test_isin():
1726
values = [("foo", 2), ("bar", 3), ("quux", 4)]
1827

pandas/tests/indexes/multi/test_join.py

+19
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import pytest
33

44
from pandas import (
5+
DataFrame,
56
Index,
67
Interval,
78
MultiIndex,
@@ -158,3 +159,21 @@ def test_join_overlapping_interval_level():
158159
result = idx_1.join(idx_2, how="outer")
159160

160161
tm.assert_index_equal(result, expected)
162+
163+
164+
def test_join_multi_with_nan():
165+
# GH29252
166+
df1 = DataFrame(
167+
data={"col1": [1.1, 1.2]},
168+
index=MultiIndex.from_product([["A"], [1.0, 2.0]], names=["id1", "id2"]),
169+
)
170+
df2 = DataFrame(
171+
data={"col2": [2.1, 2.2]},
172+
index=MultiIndex.from_product([["A"], [np.NaN, 2.0]], names=["id1", "id2"]),
173+
)
174+
result = df1.join(df2)
175+
expected = DataFrame(
176+
data={"col1": [1.1, 1.2], "col2": [np.nan, 2.2]},
177+
index=MultiIndex.from_product([["A"], [1.0, 2.0]], names=["id1", "id2"]),
178+
)
179+
tm.assert_frame_equal(result, expected)

pandas/tests/indexes/multi/test_reindex.py

+12
Original file line numberDiff line numberDiff line change
@@ -159,3 +159,15 @@ def test_reindex_limit_arg_with_multiindex():
159159
match="limit argument only valid if doing pad, backfill or nearest reindexing",
160160
):
161161
df.reindex(new_idx, fill_value=0, limit=1)
162+
163+
164+
def test_reindex_with_none_in_nested_multiindex():
165+
# GH42883
166+
index = MultiIndex.from_tuples([(("a", None), 1), (("b", None), 2)])
167+
index2 = MultiIndex.from_tuples([(("b", None), 2), (("a", None), 1)])
168+
df1_dtype = pd.DataFrame([1, 2], index=index)
169+
df2_dtype = pd.DataFrame([2, 1], index=index2)
170+
171+
result = df1_dtype.reindex_like(df2_dtype)
172+
expected = df2_dtype
173+
tm.assert_frame_equal(result, expected)

pandas/tests/indexes/multi/test_setops.py

+19-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import pandas as pd
55
from pandas import (
66
CategoricalIndex,
7+
DataFrame,
78
Index,
89
IntervalIndex,
910
MultiIndex,
@@ -548,6 +549,15 @@ def test_intersection_with_missing_values_on_both_sides(nulls_fixture):
548549
tm.assert_index_equal(result, expected)
549550

550551

552+
def test_union_with_missing_values_on_both_sides(nulls_fixture):
553+
# GH#38623
554+
mi1 = MultiIndex.from_arrays([[1, nulls_fixture]])
555+
mi2 = MultiIndex.from_arrays([[1, nulls_fixture, 3]])
556+
result = mi1.union(mi2)
557+
expected = MultiIndex.from_arrays([[1, 3, nulls_fixture]])
558+
tm.assert_index_equal(result, expected)
559+
560+
551561
@pytest.mark.parametrize("dtype", ["float64", "Float64"])
552562
@pytest.mark.parametrize("sort", [None, False])
553563
def test_union_nan_got_duplicated(dtype, sort):
@@ -651,7 +661,6 @@ def test_union_keep_dtype_precision(any_real_numeric_dtype):
651661

652662
def test_union_keep_ea_dtype_with_na(any_numeric_ea_dtype):
653663
# GH#48498
654-
655664
arr1 = Series([4, pd.NA], dtype=any_numeric_ea_dtype)
656665
arr2 = Series([1, pd.NA], dtype=any_numeric_ea_dtype)
657666
midx = MultiIndex.from_arrays([arr1, [2, 1]], names=["a", None])
@@ -695,3 +704,12 @@ def test_intersection_keep_ea_dtypes(val, any_numeric_ea_dtype):
695704
result = midx.intersection(midx2)
696705
expected = MultiIndex.from_arrays([Series([2], dtype=any_numeric_ea_dtype), [1]])
697706
tm.assert_index_equal(result, expected)
707+
708+
709+
def test_union_with_na_when_constructing_dataframe():
710+
# GH43222
711+
series1 = Series((1,), index=MultiIndex.from_tuples(((None, None),)))
712+
series2 = Series((10, 20), index=MultiIndex.from_tuples(((None, None), ("a", "b"))))
713+
result = DataFrame([series1, series2])
714+
expected = DataFrame({(np.nan, np.nan): [1.0, 10.0], ("a", "b"): [np.nan, 20.0]})
715+
tm.assert_frame_equal(result, expected)

pandas/tests/indexing/multiindex/test_multiindex.py

+12
Original file line numberDiff line numberDiff line change
@@ -216,3 +216,15 @@ def test_multiindex_repeated_keys(self):
216216
],
217217
Series([1, 1, 2, 2], MultiIndex.from_arrays([["a", "a", "b", "b"]])),
218218
)
219+
220+
def test_multiindex_with_na_missing_key(self):
221+
# GH46173
222+
df = DataFrame.from_dict(
223+
{
224+
("foo",): [1, 2, 3],
225+
("bar",): [5, 6, 7],
226+
(None,): [8, 9, 0],
227+
}
228+
)
229+
with pytest.raises(KeyError, match="missing_key"):
230+
df[[("missing_key",)]]

0 commit comments

Comments
 (0)