From 7754bcb2b1859d5504b5f62f75f44c68ed2d2e8a Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Mon, 30 Mar 2020 12:47:43 -0700 Subject: [PATCH] REF: PeriodIndex test_indexing tests --- pandas/tests/indexes/period/test_indexing.py | 676 ++++++++---------- pandas/tests/indexes/period/test_monotonic.py | 39 + pandas/tests/indexing/test_loc.py | 11 + pandas/tests/indexing/test_scalar.py | 11 +- 4 files changed, 374 insertions(+), 363 deletions(-) create mode 100644 pandas/tests/indexes/period/test_monotonic.py diff --git a/pandas/tests/indexes/period/test_indexing.py b/pandas/tests/indexes/period/test_indexing.py index a4c6764d065c9..39688e5b92380 100644 --- a/pandas/tests/indexes/period/test_indexing.py +++ b/pandas/tests/indexes/period/test_indexing.py @@ -216,165 +216,7 @@ def test_getitem_day(self): s[v] -class TestWhere: - @pytest.mark.parametrize("klass", [list, tuple, np.array, Series]) - def test_where(self, klass): - i = period_range("20130101", periods=5, freq="D") - cond = [True] * len(i) - expected = i - result = i.where(klass(cond)) - tm.assert_index_equal(result, expected) - - cond = [False] + [True] * (len(i) - 1) - expected = PeriodIndex([NaT] + i[1:].tolist(), freq="D") - result = i.where(klass(cond)) - tm.assert_index_equal(result, expected) - - def test_where_other(self): - i = period_range("20130101", periods=5, freq="D") - for arr in [np.nan, NaT]: - result = i.where(notna(i), other=np.nan) - expected = i - tm.assert_index_equal(result, expected) - - i2 = i.copy() - i2 = PeriodIndex([NaT, NaT] + i[2:].tolist(), freq="D") - result = i.where(notna(i2), i2) - tm.assert_index_equal(result, i2) - - i2 = i.copy() - i2 = PeriodIndex([NaT, NaT] + i[2:].tolist(), freq="D") - result = i.where(notna(i2), i2.values) - tm.assert_index_equal(result, i2) - - def test_where_invalid_dtypes(self): - pi = period_range("20130101", periods=5, freq="D") - - i2 = pi.copy() - i2 = PeriodIndex([NaT, NaT] + pi[2:].tolist(), freq="D") - - with pytest.raises(TypeError, match="Where requires matching dtype"): - pi.where(notna(i2), i2.asi8) - - with pytest.raises(TypeError, match="Where requires matching dtype"): - pi.where(notna(i2), i2.asi8.view("timedelta64[ns]")) - - with pytest.raises(TypeError, match="Where requires matching dtype"): - pi.where(notna(i2), i2.to_timestamp("S")) - - -class TestTake: - def test_take(self): - # GH#10295 - idx1 = period_range("2011-01-01", "2011-01-31", freq="D", name="idx") - - for idx in [idx1]: - result = idx.take([0]) - assert result == Period("2011-01-01", freq="D") - - result = idx.take([5]) - assert result == Period("2011-01-06", freq="D") - - result = idx.take([0, 1, 2]) - expected = period_range("2011-01-01", "2011-01-03", freq="D", name="idx") - tm.assert_index_equal(result, expected) - assert result.freq == "D" - assert result.freq == expected.freq - - result = idx.take([0, 2, 4]) - expected = PeriodIndex( - ["2011-01-01", "2011-01-03", "2011-01-05"], freq="D", name="idx" - ) - tm.assert_index_equal(result, expected) - assert result.freq == expected.freq - assert result.freq == "D" - - result = idx.take([7, 4, 1]) - expected = PeriodIndex( - ["2011-01-08", "2011-01-05", "2011-01-02"], freq="D", name="idx" - ) - tm.assert_index_equal(result, expected) - assert result.freq == expected.freq - assert result.freq == "D" - - result = idx.take([3, 2, 5]) - expected = PeriodIndex( - ["2011-01-04", "2011-01-03", "2011-01-06"], freq="D", name="idx" - ) - tm.assert_index_equal(result, expected) - assert result.freq == expected.freq - assert result.freq == "D" - - result = idx.take([-3, 2, 5]) - expected = PeriodIndex( - ["2011-01-29", "2011-01-03", "2011-01-06"], freq="D", name="idx" - ) - tm.assert_index_equal(result, expected) - assert result.freq == expected.freq - assert result.freq == "D" - - def test_take_misc(self): - index = period_range(start="1/1/10", end="12/31/12", freq="D", name="idx") - expected = PeriodIndex( - [ - datetime(2010, 1, 6), - datetime(2010, 1, 7), - datetime(2010, 1, 9), - datetime(2010, 1, 13), - ], - freq="D", - name="idx", - ) - - taken1 = index.take([5, 6, 8, 12]) - taken2 = index[[5, 6, 8, 12]] - - for taken in [taken1, taken2]: - tm.assert_index_equal(taken, expected) - assert isinstance(taken, PeriodIndex) - assert taken.freq == index.freq - assert taken.name == expected.name - - def test_take_fill_value(self): - # GH#12631 - idx = PeriodIndex( - ["2011-01-01", "2011-02-01", "2011-03-01"], name="xxx", freq="D" - ) - result = idx.take(np.array([1, 0, -1])) - expected = PeriodIndex( - ["2011-02-01", "2011-01-01", "2011-03-01"], name="xxx", freq="D" - ) - tm.assert_index_equal(result, expected) - - # fill_value - result = idx.take(np.array([1, 0, -1]), fill_value=True) - expected = PeriodIndex( - ["2011-02-01", "2011-01-01", "NaT"], name="xxx", freq="D" - ) - tm.assert_index_equal(result, expected) - - # allow_fill=False - result = idx.take(np.array([1, 0, -1]), allow_fill=False, fill_value=True) - expected = PeriodIndex( - ["2011-02-01", "2011-01-01", "2011-03-01"], name="xxx", freq="D" - ) - tm.assert_index_equal(result, expected) - - msg = ( - "When allow_fill=True and fill_value is not None, " - "all indices must be >= -1" - ) - with pytest.raises(ValueError, match=msg): - idx.take(np.array([1, 0, -2]), fill_value=True) - with pytest.raises(ValueError, match=msg): - idx.take(np.array([1, 0, -5]), fill_value=True) - - msg = "index -5 is out of bounds for( axis 0 with)? size 3" - with pytest.raises(IndexError, match=msg): - idx.take(np.array([1, -5])) - - -class TestIndexing: +class TestGetLoc: def test_get_loc_msg(self): idx = period_range("2000-1-1", freq="A", periods=10) bad_period = Period("2012", "A") @@ -465,153 +307,68 @@ def test_get_loc_integer(self): with pytest.raises(KeyError, match="46"): pi2.get_loc(46) - @pytest.mark.parametrize("freq", ["H", "D"]) - def test_get_value_datetime_hourly(self, freq): - # get_loc and get_value should treat datetime objects symmetrically - dti = date_range("2016-01-01", periods=3, freq="MS") - pi = dti.to_period(freq) - ser = pd.Series(range(7, 10), index=pi) + # TODO: This method came from test_period; de-dup with version above + def test_get_loc2(self): + idx = period_range("2000-01-01", periods=3) - ts = dti[0] + for method in [None, "pad", "backfill", "nearest"]: + assert idx.get_loc(idx[1], method) == 1 + assert idx.get_loc(idx[1].asfreq("H", how="start"), method) == 1 + assert idx.get_loc(idx[1].to_timestamp(), method) == 1 + assert idx.get_loc(idx[1].to_timestamp().to_pydatetime(), method) == 1 + assert idx.get_loc(str(idx[1]), method) == 1 - assert pi.get_loc(ts) == 0 - assert pi.get_value(ser, ts) == 7 - assert ser[ts] == 7 - assert ser.loc[ts] == 7 + idx = period_range("2000-01-01", periods=5)[::2] + assert idx.get_loc("2000-01-02T12", method="nearest", tolerance="1 day") == 1 + assert ( + idx.get_loc("2000-01-02T12", method="nearest", tolerance=Timedelta("1D")) + == 1 + ) + assert ( + idx.get_loc( + "2000-01-02T12", method="nearest", tolerance=np.timedelta64(1, "D") + ) + == 1 + ) + assert ( + idx.get_loc("2000-01-02T12", method="nearest", tolerance=timedelta(1)) == 1 + ) - ts2 = ts + Timedelta(hours=3) - if freq == "H": - with pytest.raises(KeyError, match="2016-01-01 03:00"): - pi.get_loc(ts2) - with pytest.raises(KeyError, match="2016-01-01 03:00"): - pi.get_value(ser, ts2) - with pytest.raises(KeyError, match="2016-01-01 03:00"): - ser[ts2] - with pytest.raises(KeyError, match="2016-01-01 03:00"): - ser.loc[ts2] - else: - assert pi.get_loc(ts2) == 0 - assert pi.get_value(ser, ts2) == 7 - assert ser[ts2] == 7 - assert ser.loc[ts2] == 7 + msg = "unit abbreviation w/o a number" + with pytest.raises(ValueError, match=msg): + idx.get_loc("2000-01-10", method="nearest", tolerance="foo") - def test_get_value_integer(self): - msg = "index 16801 is out of bounds for axis 0 with size 3" - dti = date_range("2016-01-01", periods=3) - pi = dti.to_period("D") - ser = pd.Series(range(3), index=pi) - with pytest.raises(IndexError, match=msg): - pi.get_value(ser, 16801) + msg = "Input has different freq=None from PeriodArray\\(freq=D\\)" + with pytest.raises(ValueError, match=msg): + idx.get_loc("2000-01-10", method="nearest", tolerance="1 hour") + with pytest.raises(KeyError, match=r"^Period\('2000-01-10', 'D'\)$"): + idx.get_loc("2000-01-10", method="nearest", tolerance="1 day") + with pytest.raises( + ValueError, match="list-like tolerance size must match target index size" + ): + idx.get_loc( + "2000-01-10", + method="nearest", + tolerance=[ + Timedelta("1 day").to_timedelta64(), + Timedelta("1 day").to_timedelta64(), + ], + ) - msg = "index 46 is out of bounds for axis 0 with size 3" - pi2 = dti.to_period("Y") # duplicates, ordinals are all 46 - ser2 = pd.Series(range(3), index=pi2) - with pytest.raises(IndexError, match=msg): - pi2.get_value(ser2, 46) - def test_is_monotonic_increasing(self): +class TestGetIndexer: + def test_get_indexer(self): # GH 17717 - p0 = Period("2017-09-01") - p1 = Period("2017-09-02") - p2 = Period("2017-09-03") - - idx_inc0 = PeriodIndex([p0, p1, p2]) - idx_inc1 = PeriodIndex([p0, p1, p1]) - idx_dec0 = PeriodIndex([p2, p1, p0]) - idx_dec1 = PeriodIndex([p2, p1, p1]) - idx = PeriodIndex([p1, p2, p0]) + p1 = Period("2017-09-01") + p2 = Period("2017-09-04") + p3 = Period("2017-09-07") - assert idx_inc0.is_monotonic_increasing is True - assert idx_inc1.is_monotonic_increasing is True - assert idx_dec0.is_monotonic_increasing is False - assert idx_dec1.is_monotonic_increasing is False - assert idx.is_monotonic_increasing is False + tp0 = Period("2017-08-31") + tp1 = Period("2017-09-02") + tp2 = Period("2017-09-05") + tp3 = Period("2017-09-09") - def test_is_monotonic_decreasing(self): - # GH 17717 - p0 = Period("2017-09-01") - p1 = Period("2017-09-02") - p2 = Period("2017-09-03") - - idx_inc0 = PeriodIndex([p0, p1, p2]) - idx_inc1 = PeriodIndex([p0, p1, p1]) - idx_dec0 = PeriodIndex([p2, p1, p0]) - idx_dec1 = PeriodIndex([p2, p1, p1]) - idx = PeriodIndex([p1, p2, p0]) - - assert idx_inc0.is_monotonic_decreasing is False - assert idx_inc1.is_monotonic_decreasing is False - assert idx_dec0.is_monotonic_decreasing is True - assert idx_dec1.is_monotonic_decreasing is True - assert idx.is_monotonic_decreasing is False - - def test_contains(self): - # GH 17717 - p0 = Period("2017-09-01") - p1 = Period("2017-09-02") - p2 = Period("2017-09-03") - p3 = Period("2017-09-04") - - ps0 = [p0, p1, p2] - idx0 = PeriodIndex(ps0) - ser = pd.Series(range(6, 9), index=idx0) - - for p in ps0: - assert p in idx0 - assert str(p) in idx0 - - # GH#31172 - # Higher-resolution period-like are _not_ considered as contained - key = "2017-09-01 00:00:01" - assert key not in idx0 - with pytest.raises(KeyError, match=key): - idx0.get_loc(key) - with pytest.raises(KeyError, match=key): - idx0.get_value(ser, key) - - assert "2017-09" in idx0 - - assert p3 not in idx0 - - def test_get_value(self): - # GH 17717 - p0 = Period("2017-09-01") - p1 = Period("2017-09-02") - p2 = Period("2017-09-03") - - idx0 = PeriodIndex([p0, p1, p2]) - input0 = pd.Series(np.array([1, 2, 3]), index=idx0) - expected0 = 2 - - result0 = idx0.get_value(input0, p1) - assert result0 == expected0 - - idx1 = PeriodIndex([p1, p1, p2]) - input1 = pd.Series(np.array([1, 2, 3]), index=idx1) - expected1 = input1.iloc[[0, 1]] - - result1 = idx1.get_value(input1, p1) - tm.assert_series_equal(result1, expected1) - - idx2 = PeriodIndex([p1, p2, p1]) - input2 = pd.Series(np.array([1, 2, 3]), index=idx2) - expected2 = input2.iloc[[0, 2]] - - result2 = idx2.get_value(input2, p1) - tm.assert_series_equal(result2, expected2) - - def test_get_indexer(self): - # GH 17717 - p1 = Period("2017-09-01") - p2 = Period("2017-09-04") - p3 = Period("2017-09-07") - - tp0 = Period("2017-08-31") - tp1 = Period("2017-09-02") - tp2 = Period("2017-09-05") - tp3 = Period("2017-09-09") - - idx = PeriodIndex([p1, p2, p3]) + idx = PeriodIndex([p1, p2, p3]) tm.assert_numpy_array_equal( idx.get_indexer(idx), np.array([0, 1, 2], dtype=np.intp) @@ -677,54 +434,6 @@ def test_get_indexer_non_unique(self): tm.assert_numpy_array_equal(result[0], expected_indexer) tm.assert_numpy_array_equal(result[1], expected_missing) - # TODO: This method came from test_period; de-dup with version above - def test_get_loc2(self): - idx = period_range("2000-01-01", periods=3) - - for method in [None, "pad", "backfill", "nearest"]: - assert idx.get_loc(idx[1], method) == 1 - assert idx.get_loc(idx[1].asfreq("H", how="start"), method) == 1 - assert idx.get_loc(idx[1].to_timestamp(), method) == 1 - assert idx.get_loc(idx[1].to_timestamp().to_pydatetime(), method) == 1 - assert idx.get_loc(str(idx[1]), method) == 1 - - idx = period_range("2000-01-01", periods=5)[::2] - assert idx.get_loc("2000-01-02T12", method="nearest", tolerance="1 day") == 1 - assert ( - idx.get_loc("2000-01-02T12", method="nearest", tolerance=Timedelta("1D")) - == 1 - ) - assert ( - idx.get_loc( - "2000-01-02T12", method="nearest", tolerance=np.timedelta64(1, "D") - ) - == 1 - ) - assert ( - idx.get_loc("2000-01-02T12", method="nearest", tolerance=timedelta(1)) == 1 - ) - - msg = "unit abbreviation w/o a number" - with pytest.raises(ValueError, match=msg): - idx.get_loc("2000-01-10", method="nearest", tolerance="foo") - - msg = "Input has different freq=None from PeriodArray\\(freq=D\\)" - with pytest.raises(ValueError, match=msg): - idx.get_loc("2000-01-10", method="nearest", tolerance="1 hour") - with pytest.raises(KeyError, match=r"^Period\('2000-01-10', 'D'\)$"): - idx.get_loc("2000-01-10", method="nearest", tolerance="1 day") - with pytest.raises( - ValueError, match="list-like tolerance size must match target index size" - ): - idx.get_loc( - "2000-01-10", - method="nearest", - tolerance=[ - Timedelta("1 day").to_timedelta64(), - Timedelta("1 day").to_timedelta64(), - ], - ) - # TODO: This method came from test_period; de-dup with version above def test_get_indexer2(self): idx = period_range("2000-01-01", periods=3).asfreq("H", how="start") @@ -778,23 +487,266 @@ def test_get_indexer2(self): ): idx.get_indexer(target, "nearest", tolerance=tol_bad) - def test_indexing(self): - # GH 4390, iat incorrectly indexing - index = period_range("1/1/2001", periods=10) - s = Series(np.random.randn(10), index=index) - expected = s[index[0]] - result = s.iat[0] - assert expected == result - - def test_period_index_indexer(self): - # GH4125 - idx = period_range("2002-01", "2003-12", freq="M") - df = pd.DataFrame(np.random.randn(24, 10), index=idx) - tm.assert_frame_equal(df, df.loc[idx]) - tm.assert_frame_equal(df, df.loc[list(idx)]) - tm.assert_frame_equal(df, df.loc[list(idx)]) - tm.assert_frame_equal(df.iloc[0:5], df.loc[idx[0:5]]) - tm.assert_frame_equal(df, df.loc[list(idx)]) + +class TestWhere: + @pytest.mark.parametrize("klass", [list, tuple, np.array, Series]) + def test_where(self, klass): + i = period_range("20130101", periods=5, freq="D") + cond = [True] * len(i) + expected = i + result = i.where(klass(cond)) + tm.assert_index_equal(result, expected) + + cond = [False] + [True] * (len(i) - 1) + expected = PeriodIndex([NaT] + i[1:].tolist(), freq="D") + result = i.where(klass(cond)) + tm.assert_index_equal(result, expected) + + def test_where_other(self): + i = period_range("20130101", periods=5, freq="D") + for arr in [np.nan, NaT]: + result = i.where(notna(i), other=np.nan) + expected = i + tm.assert_index_equal(result, expected) + + i2 = i.copy() + i2 = PeriodIndex([NaT, NaT] + i[2:].tolist(), freq="D") + result = i.where(notna(i2), i2) + tm.assert_index_equal(result, i2) + + i2 = i.copy() + i2 = PeriodIndex([NaT, NaT] + i[2:].tolist(), freq="D") + result = i.where(notna(i2), i2.values) + tm.assert_index_equal(result, i2) + + def test_where_invalid_dtypes(self): + pi = period_range("20130101", periods=5, freq="D") + + i2 = pi.copy() + i2 = PeriodIndex([NaT, NaT] + pi[2:].tolist(), freq="D") + + with pytest.raises(TypeError, match="Where requires matching dtype"): + pi.where(notna(i2), i2.asi8) + + with pytest.raises(TypeError, match="Where requires matching dtype"): + pi.where(notna(i2), i2.asi8.view("timedelta64[ns]")) + + with pytest.raises(TypeError, match="Where requires matching dtype"): + pi.where(notna(i2), i2.to_timestamp("S")) + + +class TestTake: + def test_take(self): + # GH#10295 + idx1 = period_range("2011-01-01", "2011-01-31", freq="D", name="idx") + + for idx in [idx1]: + result = idx.take([0]) + assert result == Period("2011-01-01", freq="D") + + result = idx.take([5]) + assert result == Period("2011-01-06", freq="D") + + result = idx.take([0, 1, 2]) + expected = period_range("2011-01-01", "2011-01-03", freq="D", name="idx") + tm.assert_index_equal(result, expected) + assert result.freq == "D" + assert result.freq == expected.freq + + result = idx.take([0, 2, 4]) + expected = PeriodIndex( + ["2011-01-01", "2011-01-03", "2011-01-05"], freq="D", name="idx" + ) + tm.assert_index_equal(result, expected) + assert result.freq == expected.freq + assert result.freq == "D" + + result = idx.take([7, 4, 1]) + expected = PeriodIndex( + ["2011-01-08", "2011-01-05", "2011-01-02"], freq="D", name="idx" + ) + tm.assert_index_equal(result, expected) + assert result.freq == expected.freq + assert result.freq == "D" + + result = idx.take([3, 2, 5]) + expected = PeriodIndex( + ["2011-01-04", "2011-01-03", "2011-01-06"], freq="D", name="idx" + ) + tm.assert_index_equal(result, expected) + assert result.freq == expected.freq + assert result.freq == "D" + + result = idx.take([-3, 2, 5]) + expected = PeriodIndex( + ["2011-01-29", "2011-01-03", "2011-01-06"], freq="D", name="idx" + ) + tm.assert_index_equal(result, expected) + assert result.freq == expected.freq + assert result.freq == "D" + + def test_take_misc(self): + index = period_range(start="1/1/10", end="12/31/12", freq="D", name="idx") + expected = PeriodIndex( + [ + datetime(2010, 1, 6), + datetime(2010, 1, 7), + datetime(2010, 1, 9), + datetime(2010, 1, 13), + ], + freq="D", + name="idx", + ) + + taken1 = index.take([5, 6, 8, 12]) + taken2 = index[[5, 6, 8, 12]] + + for taken in [taken1, taken2]: + tm.assert_index_equal(taken, expected) + assert isinstance(taken, PeriodIndex) + assert taken.freq == index.freq + assert taken.name == expected.name + + def test_take_fill_value(self): + # GH#12631 + idx = PeriodIndex( + ["2011-01-01", "2011-02-01", "2011-03-01"], name="xxx", freq="D" + ) + result = idx.take(np.array([1, 0, -1])) + expected = PeriodIndex( + ["2011-02-01", "2011-01-01", "2011-03-01"], name="xxx", freq="D" + ) + tm.assert_index_equal(result, expected) + + # fill_value + result = idx.take(np.array([1, 0, -1]), fill_value=True) + expected = PeriodIndex( + ["2011-02-01", "2011-01-01", "NaT"], name="xxx", freq="D" + ) + tm.assert_index_equal(result, expected) + + # allow_fill=False + result = idx.take(np.array([1, 0, -1]), allow_fill=False, fill_value=True) + expected = PeriodIndex( + ["2011-02-01", "2011-01-01", "2011-03-01"], name="xxx", freq="D" + ) + tm.assert_index_equal(result, expected) + + msg = ( + "When allow_fill=True and fill_value is not None, " + "all indices must be >= -1" + ) + with pytest.raises(ValueError, match=msg): + idx.take(np.array([1, 0, -2]), fill_value=True) + with pytest.raises(ValueError, match=msg): + idx.take(np.array([1, 0, -5]), fill_value=True) + + msg = "index -5 is out of bounds for( axis 0 with)? size 3" + with pytest.raises(IndexError, match=msg): + idx.take(np.array([1, -5])) + + +class TestGetValue: + def test_get_value(self): + # GH 17717 + p0 = Period("2017-09-01") + p1 = Period("2017-09-02") + p2 = Period("2017-09-03") + + idx0 = PeriodIndex([p0, p1, p2]) + input0 = pd.Series(np.array([1, 2, 3]), index=idx0) + expected0 = 2 + + result0 = idx0.get_value(input0, p1) + assert result0 == expected0 + + idx1 = PeriodIndex([p1, p1, p2]) + input1 = pd.Series(np.array([1, 2, 3]), index=idx1) + expected1 = input1.iloc[[0, 1]] + + result1 = idx1.get_value(input1, p1) + tm.assert_series_equal(result1, expected1) + + idx2 = PeriodIndex([p1, p2, p1]) + input2 = pd.Series(np.array([1, 2, 3]), index=idx2) + expected2 = input2.iloc[[0, 2]] + + result2 = idx2.get_value(input2, p1) + tm.assert_series_equal(result2, expected2) + + @pytest.mark.parametrize("freq", ["H", "D"]) + def test_get_value_datetime_hourly(self, freq): + # get_loc and get_value should treat datetime objects symmetrically + dti = date_range("2016-01-01", periods=3, freq="MS") + pi = dti.to_period(freq) + ser = pd.Series(range(7, 10), index=pi) + + ts = dti[0] + + assert pi.get_loc(ts) == 0 + assert pi.get_value(ser, ts) == 7 + assert ser[ts] == 7 + assert ser.loc[ts] == 7 + + ts2 = ts + Timedelta(hours=3) + if freq == "H": + with pytest.raises(KeyError, match="2016-01-01 03:00"): + pi.get_loc(ts2) + with pytest.raises(KeyError, match="2016-01-01 03:00"): + pi.get_value(ser, ts2) + with pytest.raises(KeyError, match="2016-01-01 03:00"): + ser[ts2] + with pytest.raises(KeyError, match="2016-01-01 03:00"): + ser.loc[ts2] + else: + assert pi.get_loc(ts2) == 0 + assert pi.get_value(ser, ts2) == 7 + assert ser[ts2] == 7 + assert ser.loc[ts2] == 7 + + def test_get_value_integer(self): + msg = "index 16801 is out of bounds for axis 0 with size 3" + dti = date_range("2016-01-01", periods=3) + pi = dti.to_period("D") + ser = pd.Series(range(3), index=pi) + with pytest.raises(IndexError, match=msg): + pi.get_value(ser, 16801) + + msg = "index 46 is out of bounds for axis 0 with size 3" + pi2 = dti.to_period("Y") # duplicates, ordinals are all 46 + ser2 = pd.Series(range(3), index=pi2) + with pytest.raises(IndexError, match=msg): + pi2.get_value(ser2, 46) + + +class TestContains: + def test_contains(self): + # GH 17717 + p0 = Period("2017-09-01") + p1 = Period("2017-09-02") + p2 = Period("2017-09-03") + p3 = Period("2017-09-04") + + ps0 = [p0, p1, p2] + idx0 = PeriodIndex(ps0) + ser = pd.Series(range(6, 9), index=idx0) + + for p in ps0: + assert p in idx0 + assert str(p) in idx0 + + # GH#31172 + # Higher-resolution period-like are _not_ considered as contained + key = "2017-09-01 00:00:01" + assert key not in idx0 + with pytest.raises(KeyError, match=key): + idx0.get_loc(key) + with pytest.raises(KeyError, match=key): + idx0.get_value(ser, key) + + assert "2017-09" in idx0 + + assert p3 not in idx0 class TestAsOfLocs: diff --git a/pandas/tests/indexes/period/test_monotonic.py b/pandas/tests/indexes/period/test_monotonic.py new file mode 100644 index 0000000000000..e06e7da1773f5 --- /dev/null +++ b/pandas/tests/indexes/period/test_monotonic.py @@ -0,0 +1,39 @@ +from pandas import Period, PeriodIndex + + +def test_is_monotonic_increasing(): + # GH#17717 + p0 = Period("2017-09-01") + p1 = Period("2017-09-02") + p2 = Period("2017-09-03") + + idx_inc0 = PeriodIndex([p0, p1, p2]) + idx_inc1 = PeriodIndex([p0, p1, p1]) + idx_dec0 = PeriodIndex([p2, p1, p0]) + idx_dec1 = PeriodIndex([p2, p1, p1]) + idx = PeriodIndex([p1, p2, p0]) + + assert idx_inc0.is_monotonic_increasing is True + assert idx_inc1.is_monotonic_increasing is True + assert idx_dec0.is_monotonic_increasing is False + assert idx_dec1.is_monotonic_increasing is False + assert idx.is_monotonic_increasing is False + + +def test_is_monotonic_decreasing(): + # GH#17717 + p0 = Period("2017-09-01") + p1 = Period("2017-09-02") + p2 = Period("2017-09-03") + + idx_inc0 = PeriodIndex([p0, p1, p2]) + idx_inc1 = PeriodIndex([p0, p1, p1]) + idx_dec0 = PeriodIndex([p2, p1, p0]) + idx_dec1 = PeriodIndex([p2, p1, p1]) + idx = PeriodIndex([p1, p2, p0]) + + assert idx_inc0.is_monotonic_decreasing is False + assert idx_inc1.is_monotonic_decreasing is False + assert idx_dec0.is_monotonic_decreasing is True + assert idx_dec1.is_monotonic_decreasing is True + assert idx.is_monotonic_decreasing is False diff --git a/pandas/tests/indexing/test_loc.py b/pandas/tests/indexing/test_loc.py index ee92e5a69204d..d1f67981b1ec5 100644 --- a/pandas/tests/indexing/test_loc.py +++ b/pandas/tests/indexing/test_loc.py @@ -1095,3 +1095,14 @@ def test_loc_datetimelike_mismatched_dtypes(): with pytest.raises(KeyError, match=msg): df["a"].loc[tdi] + + +def test_loc_with_period_index_indexer(): + # GH#4125 + idx = pd.period_range("2002-01", "2003-12", freq="M") + df = pd.DataFrame(np.random.randn(24, 10), index=idx) + tm.assert_frame_equal(df, df.loc[idx]) + tm.assert_frame_equal(df, df.loc[list(idx)]) + tm.assert_frame_equal(df, df.loc[list(idx)]) + tm.assert_frame_equal(df.iloc[0:5], df.loc[idx[0:5]]) + tm.assert_frame_equal(df, df.loc[list(idx)]) diff --git a/pandas/tests/indexing/test_scalar.py b/pandas/tests/indexing/test_scalar.py index 25939e63c256b..61d109344568c 100644 --- a/pandas/tests/indexing/test_scalar.py +++ b/pandas/tests/indexing/test_scalar.py @@ -4,7 +4,7 @@ import numpy as np import pytest -from pandas import DataFrame, Series, Timedelta, Timestamp, date_range +from pandas import DataFrame, Series, Timedelta, Timestamp, date_range, period_range import pandas._testing as tm from pandas.tests.indexing.common import Base @@ -302,3 +302,12 @@ def test_iat_dont_wrap_object_datetimelike(): assert result is ser2[1] assert isinstance(result, timedelta) assert not isinstance(result, Timedelta) + + +def test_iat_series_with_period_index(): + # GH 4390, iat incorrectly indexing + index = period_range("1/1/2001", periods=10) + ser = Series(np.random.randn(10), index=index) + expected = ser[index[0]] + result = ser.iat[0] + assert expected == result