diff --git a/pandas/tests/frame/methods/test_reset_index.py b/pandas/tests/frame/methods/test_reset_index.py index 0de7eef3aff9f..3be45e2d48e19 100644 --- a/pandas/tests/frame/methods/test_reset_index.py +++ b/pandas/tests/frame/methods/test_reset_index.py @@ -516,6 +516,32 @@ def test_reset_index_with_drop( assert len(deleveled.columns) == len(ymd.columns) assert deleveled.index.name == ymd.index.name + @pytest.mark.parametrize( + "ix_data, exp_data", + [ + ( + [(pd.NaT, 1), (pd.NaT, 2)], + {"a": [pd.NaT, pd.NaT], "b": [1, 2], "x": [11, 12]}, + ), + ( + [(pd.NaT, 1), (pd.Timestamp("2020-01-01"), 2)], + {"a": [pd.NaT, pd.Timestamp("2020-01-01")], "b": [1, 2], "x": [11, 12]}, + ), + ( + [(pd.NaT, 1), (pd.Timedelta(123, "d"), 2)], + {"a": [pd.NaT, pd.Timedelta(123, "d")], "b": [1, 2], "x": [11, 12]}, + ), + ], + ) + def test_reset_index_nat_multiindex(self, ix_data, exp_data): + # GH#36541: that reset_index() does not raise ValueError + ix = MultiIndex.from_tuples(ix_data, names=["a", "b"]) + result = DataFrame({"x": [11, 12]}, index=ix) + result = result.reset_index() + + expected = DataFrame(exp_data) + tm.assert_frame_equal(result, expected) + @pytest.mark.parametrize( "array, dtype", diff --git a/pandas/tests/frame/test_to_csv.py b/pandas/tests/frame/methods/test_to_csv.py similarity index 100% rename from pandas/tests/frame/test_to_csv.py rename to pandas/tests/frame/methods/test_to_csv.py diff --git a/pandas/tests/indexing/test_loc.py b/pandas/tests/indexing/test_loc.py index 3b915f13c7568..9232cc949bf7e 100644 --- a/pandas/tests/indexing/test_loc.py +++ b/pandas/tests/indexing/test_loc.py @@ -1019,6 +1019,36 @@ def test_loc_preserve_names(self, multiindex_year_month_day_dataframe_random_dat assert result.index.name == ymd.index.names[2] assert result2.index.name == ymd.index.names[2] + def test_loc_getitem_multiindex_nonunique_len_zero(self): + # GH#13691 + mi = MultiIndex.from_product([[0], [1, 1]]) + ser = Series(0, index=mi) + + res = ser.loc[[]] + + expected = ser[:0] + tm.assert_series_equal(res, expected) + + res2 = ser.loc[ser.iloc[0:0]] + tm.assert_series_equal(res2, expected) + + def test_loc_getitem_access_none_value_in_multiindex(self): + # GH#34318: test that you can access a None value using .loc + # through a Multiindex + + ser = Series([None], pd.MultiIndex.from_arrays([["Level1"], ["Level2"]])) + result = ser.loc[("Level1", "Level2")] + assert result is None + + midx = MultiIndex.from_product([["Level1"], ["Level2_a", "Level2_b"]]) + ser = Series([None] * len(midx), dtype=object, index=midx) + result = ser.loc[("Level1", "Level2_a")] + assert result is None + + ser = Series([1] * len(midx), dtype=object, index=midx) + result = ser.loc[("Level1", "Level2_a")] + assert result == 1 + def test_series_loc_getitem_label_list_missing_values(): # gh-11428 diff --git a/pandas/tests/series/indexing/test_callable.py b/pandas/tests/series/indexing/test_callable.py deleted file mode 100644 index fe575cf146641..0000000000000 --- a/pandas/tests/series/indexing/test_callable.py +++ /dev/null @@ -1,33 +0,0 @@ -import pandas as pd -import pandas._testing as tm - - -def test_getitem_callable(): - # GH 12533 - s = pd.Series(4, index=list("ABCD")) - result = s[lambda x: "A"] - assert result == s.loc["A"] - - result = s[lambda x: ["A", "B"]] - tm.assert_series_equal(result, s.loc[["A", "B"]]) - - result = s[lambda x: [True, False, True, True]] - tm.assert_series_equal(result, s.iloc[[0, 2, 3]]) - - -def test_setitem_callable(): - # GH 12533 - s = pd.Series([1, 2, 3, 4], index=list("ABCD")) - s[lambda x: "A"] = -1 - tm.assert_series_equal(s, pd.Series([-1, 2, 3, 4], index=list("ABCD"))) - - -def test_setitem_other_callable(): - # GH 13299 - inc = lambda x: x + 1 - - s = pd.Series([1, 2, -1, 4]) - s[s < 0] = inc - - expected = pd.Series([1, 2, inc, 4]) - tm.assert_series_equal(s, expected) diff --git a/pandas/tests/series/indexing/test_getitem.py b/pandas/tests/series/indexing/test_getitem.py index b4c861312ad3d..0da1f74d9cde6 100644 --- a/pandas/tests/series/indexing/test_getitem.py +++ b/pandas/tests/series/indexing/test_getitem.py @@ -17,6 +17,27 @@ class TestSeriesGetitemScalars: + def test_getitem_keyerror_with_int64index(self): + ser = Series(np.random.randn(6), index=[0, 0, 1, 1, 2, 2]) + + with pytest.raises(KeyError, match=r"^5$"): + ser[5] + + with pytest.raises(KeyError, match=r"^'c'$"): + ser["c"] + + # not monotonic + ser = Series(np.random.randn(6), index=[2, 2, 0, 0, 1, 1]) + + with pytest.raises(KeyError, match=r"^5$"): + ser[5] + + with pytest.raises(KeyError, match=r"^'c'$"): + ser["c"] + + def test_getitem_int64(self, datetime_series): + idx = np.int64(5) + assert datetime_series[idx] == datetime_series[5] # TODO: better name/GH ref? def test_getitem_regression(self): @@ -228,6 +249,22 @@ def test_getitem_boolean_different_order(self, string_series): tm.assert_series_equal(sel, exp) +class TestGetitemCallable: + def test_getitem_callable(self): + # GH#12533 + ser = Series(4, index=list("ABCD")) + result = ser[lambda x: "A"] + assert result == ser.loc["A"] + + result = ser[lambda x: ["A", "B"]] + expected = ser.loc[["A", "B"]] + tm.assert_series_equal(result, expected) + + result = ser[lambda x: [True, False, True, True]] + expected = ser.iloc[[0, 2, 3]] + tm.assert_series_equal(result, expected) + + def test_getitem_generator(string_series): gen = (x > 0 for x in string_series) result = string_series[gen] diff --git a/pandas/tests/series/indexing/test_multiindex.py b/pandas/tests/series/indexing/test_multiindex.py deleted file mode 100644 index ff9db275ff2df..0000000000000 --- a/pandas/tests/series/indexing/test_multiindex.py +++ /dev/null @@ -1,65 +0,0 @@ -""" test get/set & misc """ - -import pytest - -import pandas as pd -from pandas import MultiIndex, Series -import pandas._testing as tm - - -def test_access_none_value_in_multiindex(): - # GH34318: test that you can access a None value using .loc through a Multiindex - - s = Series([None], pd.MultiIndex.from_arrays([["Level1"], ["Level2"]])) - result = s.loc[("Level1", "Level2")] - assert result is None - - midx = MultiIndex.from_product([["Level1"], ["Level2_a", "Level2_b"]]) - s = Series([None] * len(midx), dtype=object, index=midx) - result = s.loc[("Level1", "Level2_a")] - assert result is None - - s = Series([1] * len(midx), dtype=object, index=midx) - result = s.loc[("Level1", "Level2_a")] - assert result == 1 - - -@pytest.mark.parametrize( - "ix_data, exp_data", - [ - ( - [(pd.NaT, 1), (pd.NaT, 2)], - {"a": [pd.NaT, pd.NaT], "b": [1, 2], "x": [11, 12]}, - ), - ( - [(pd.NaT, 1), (pd.Timestamp("2020-01-01"), 2)], - {"a": [pd.NaT, pd.Timestamp("2020-01-01")], "b": [1, 2], "x": [11, 12]}, - ), - ( - [(pd.NaT, 1), (pd.Timedelta(123, "d"), 2)], - {"a": [pd.NaT, pd.Timedelta(123, "d")], "b": [1, 2], "x": [11, 12]}, - ), - ], -) -def test_nat_multi_index(ix_data, exp_data): - # GH36541: that reset_index() does not raise ValueError - ix = pd.MultiIndex.from_tuples(ix_data, names=["a", "b"]) - result = pd.DataFrame({"x": [11, 12]}, index=ix) - result = result.reset_index() - - expected = pd.DataFrame(exp_data) - tm.assert_frame_equal(result, expected) - - -def test_loc_getitem_multiindex_nonunique_len_zero(): - # GH#13691 - mi = pd.MultiIndex.from_product([[0], [1, 1]]) - ser = Series(0, index=mi) - - res = ser.loc[[]] - - expected = ser[:0] - tm.assert_series_equal(res, expected) - - res2 = ser.loc[ser.iloc[0:0]] - tm.assert_series_equal(res2, expected) diff --git a/pandas/tests/series/indexing/test_numeric.py b/pandas/tests/series/indexing/test_numeric.py index b5bef46e95ec2..f35f1375732cb 100644 --- a/pandas/tests/series/indexing/test_numeric.py +++ b/pandas/tests/series/indexing/test_numeric.py @@ -110,27 +110,3 @@ def test_slice_floats2(): s.index = i assert len(s.loc[12.0:]) == 8 assert len(s.loc[12.5:]) == 7 - - -def test_int_indexing(): - s = Series(np.random.randn(6), index=[0, 0, 1, 1, 2, 2]) - - with pytest.raises(KeyError, match=r"^5$"): - s[5] - - with pytest.raises(KeyError, match=r"^'c'$"): - s["c"] - - # not monotonic - s = Series(np.random.randn(6), index=[2, 2, 0, 0, 1, 1]) - - with pytest.raises(KeyError, match=r"^5$"): - s[5] - - with pytest.raises(KeyError, match=r"^'c'$"): - s["c"] - - -def test_getitem_int64(datetime_series): - idx = np.int64(5) - assert datetime_series[idx] == datetime_series[5] diff --git a/pandas/tests/series/indexing/test_setitem.py b/pandas/tests/series/indexing/test_setitem.py index 3ea5f3729d793..967cf5c55845c 100644 --- a/pandas/tests/series/indexing/test_setitem.py +++ b/pandas/tests/series/indexing/test_setitem.py @@ -142,3 +142,23 @@ def test_dt64tz_setitem_does_not_mutate_dti(self): ser[::3] = NaT assert ser[0] is NaT assert dti[0] == ts + + +class TestSetitemCallable: + def test_setitem_callable_key(self): + # GH#12533 + ser = Series([1, 2, 3, 4], index=list("ABCD")) + ser[lambda x: "A"] = -1 + + expected = Series([-1, 2, 3, 4], index=list("ABCD")) + tm.assert_series_equal(ser, expected) + + def test_setitem_callable_other(self): + # GH#13299 + inc = lambda x: x + 1 + + ser = Series([1, 2, -1, 4]) + ser[ser < 0] = inc + + expected = Series([1, 2, inc, 4]) + tm.assert_series_equal(ser, expected)