diff --git a/pandas/tests/indexing/multiindex/test_setitem.py b/pandas/tests/indexing/multiindex/test_setitem.py index d732cb4d7fbbc..4e8af3f7a7759 100644 --- a/pandas/tests/indexing/multiindex/test_setitem.py +++ b/pandas/tests/indexing/multiindex/test_setitem.py @@ -173,11 +173,11 @@ def test_multiindex_setitem2(self): idx = pd.IndexSlice df = df_orig.copy() df.loc[idx[:, :, "Stock"], :] *= 2 - tm.assert_frame_equal(df, expected) + tm.assert_frame_equal(df, expected, check_index_type=False) df = df_orig.copy() df.loc[idx[:, :, "Stock"], "price"] *= 2 - tm.assert_frame_equal(df, expected) + tm.assert_frame_equal(df, expected, check_index_type=False) def test_multiindex_assignment(self): # GH3777 part 2 @@ -490,6 +490,62 @@ def test_setitem_enlargement_keep_index_names(self): ) tm.assert_frame_equal(df, expected) + def test_setitem_enlargement_multiindex_with_none(self): + # GH#59153 + # Test that we can enlarge a DataFrame with a MultiIndex + # when one or more level keys are None + index = MultiIndex.from_tuples( + [("A", "a1"), ("A", "a2"), ("B", "b1"), ("B", None)] + ) + df = DataFrame([(0.0, 6.0), (1.0, 5.0), (2.0, 4.0), (3.0, 7.0)], index=index) + + # Enlarge with a new index entry where one key is None + df.loc[("A", None), :] = [12.0, 13.0] + + expected_index = MultiIndex.from_tuples( + [("A", "a1"), ("A", "a2"), ("B", "b1"), ("B", None), ("A", None)] + ) + expected = DataFrame( + [[0.0, 6.0], [1.0, 5.0], [2.0, 4.0], [3.0, 7.0], [12.0, 13.0]], + index=expected_index, + columns=[0, 1], + ) + # check_index_type=False because None in MultiIndex causes mixed inferred_type + tm.assert_frame_equal(df, expected, check_index_type=False) + + # Test retrieval of the newly added row + result = df.loc[("A", None), :] + expected_row = Series([12.0, 13.0], index=[0, 1], name=("A", np.nan)) + tm.assert_series_equal(result, expected_row) + + def test_setitem_enlargement_multiindex_multiple_none(self): + # GH#59153 + # Test enlarging with multiple None keys in different levels + index = MultiIndex.from_tuples([("A", "a1"), ("B", "b1")]) + df = DataFrame([[1.0, 2.0], [3.0, 4.0]], index=index, columns=["x", "y"]) + + # Add row with None in first level + df.loc[(None, "c1"), :] = [5.0, 6.0] + + # Add row with None in second level + df.loc[("C", None), :] = [7.0, 8.0] + + expected_index = MultiIndex.from_tuples( + [ + ("A", "a1"), + ("B", "b1"), + (None, "c1"), + ("C", None), + ] + ) + expected = DataFrame( + [[1.0, 2.0], [3.0, 4.0], [5.0, 6.0], [7.0, 8.0]], + index=expected_index, + columns=["x", "y"], + ) + # check_index_type=False because None in MultiIndex causes mixed inferred_type + tm.assert_frame_equal(df, expected, check_index_type=False) + def test_frame_setitem_view_direct(multiindex_dataframe_random_data): # this works because we are modifying the underlying array