123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815 |
- from datetime import datetime
- import re
- import numpy as np
- import pytest
- from pandas._libs.tslibs import period as libperiod
- from pandas.errors import InvalidIndexError
- import pandas as pd
- from pandas import (
- DatetimeIndex,
- NaT,
- Period,
- PeriodIndex,
- Series,
- Timedelta,
- date_range,
- notna,
- period_range,
- )
- import pandas._testing as tm
- dti4 = date_range("2016-01-01", periods=4)
- dti = dti4[:-1]
- rng = pd.Index(range(3))
- @pytest.fixture(
- params=[
- dti,
- dti.tz_localize("UTC"),
- dti.to_period("W"),
- dti - dti[0],
- rng,
- pd.Index([1, 2, 3]),
- pd.Index([2.0, 3.0, 4.0]),
- pd.Index([4, 5, 6], dtype="u8"),
- pd.IntervalIndex.from_breaks(dti4),
- ]
- )
- def non_comparable_idx(request):
- # All have length 3
- return request.param
- class TestGetItem:
- def test_getitem_slice_keeps_name(self):
- idx = period_range("20010101", periods=10, freq="D", name="bob")
- assert idx.name == idx[1:].name
- def test_getitem(self):
- idx1 = period_range("2011-01-01", "2011-01-31", freq="D", name="idx")
- for idx in [idx1]:
- result = idx[0]
- assert result == Period("2011-01-01", freq="D")
- result = idx[-1]
- assert result == Period("2011-01-31", freq="D")
- result = idx[0:5]
- expected = period_range("2011-01-01", "2011-01-05", freq="D", name="idx")
- tm.assert_index_equal(result, expected)
- assert result.freq == expected.freq
- assert result.freq == "D"
- result = idx[0:10:2]
- expected = PeriodIndex(
- ["2011-01-01", "2011-01-03", "2011-01-05", "2011-01-07", "2011-01-09"],
- freq="D",
- name="idx",
- )
- tm.assert_index_equal(result, expected)
- assert result.freq == expected.freq
- assert result.freq == "D"
- result = idx[-20:-5:3]
- expected = PeriodIndex(
- ["2011-01-12", "2011-01-15", "2011-01-18", "2011-01-21", "2011-01-24"],
- freq="D",
- name="idx",
- )
- tm.assert_index_equal(result, expected)
- assert result.freq == expected.freq
- assert result.freq == "D"
- result = idx[4::-1]
- expected = PeriodIndex(
- ["2011-01-05", "2011-01-04", "2011-01-03", "2011-01-02", "2011-01-01"],
- freq="D",
- name="idx",
- )
- tm.assert_index_equal(result, expected)
- assert result.freq == expected.freq
- assert result.freq == "D"
- def test_getitem_index(self):
- idx = period_range("2007-01", periods=10, freq="M", name="x")
- result = idx[[1, 3, 5]]
- exp = PeriodIndex(["2007-02", "2007-04", "2007-06"], freq="M", name="x")
- tm.assert_index_equal(result, exp)
- result = idx[[True, True, False, False, False, True, True, False, False, False]]
- exp = PeriodIndex(
- ["2007-01", "2007-02", "2007-06", "2007-07"], freq="M", name="x"
- )
- tm.assert_index_equal(result, exp)
- def test_getitem_partial(self):
- rng = period_range("2007-01", periods=50, freq="M")
- ts = Series(np.random.randn(len(rng)), rng)
- with pytest.raises(KeyError, match=r"^'2006'$"):
- ts["2006"]
- result = ts["2008"]
- assert (result.index.year == 2008).all()
- result = ts["2008":"2009"]
- assert len(result) == 24
- result = ts["2008-1":"2009-12"]
- assert len(result) == 24
- result = ts["2008Q1":"2009Q4"]
- assert len(result) == 24
- result = ts[:"2009"]
- assert len(result) == 36
- result = ts["2009":]
- assert len(result) == 50 - 24
- exp = result
- result = ts[24:]
- tm.assert_series_equal(exp, result)
- ts = pd.concat([ts[10:], ts[10:]])
- msg = "left slice bound for non-unique label: '2008'"
- with pytest.raises(KeyError, match=msg):
- ts[slice("2008", "2009")]
- def test_getitem_datetime(self):
- rng = period_range(start="2012-01-01", periods=10, freq="W-MON")
- ts = Series(range(len(rng)), index=rng)
- dt1 = datetime(2011, 10, 2)
- dt4 = datetime(2012, 4, 20)
- rs = ts[dt1:dt4]
- tm.assert_series_equal(rs, ts)
- def test_getitem_nat(self):
- idx = PeriodIndex(["2011-01", "NaT", "2011-02"], freq="M")
- assert idx[0] == Period("2011-01", freq="M")
- assert idx[1] is NaT
- s = Series([0, 1, 2], index=idx)
- assert s[NaT] == 1
- s = Series(idx, index=idx)
- assert s[Period("2011-01", freq="M")] == Period("2011-01", freq="M")
- assert s[NaT] is NaT
- def test_getitem_list_periods(self):
- # GH 7710
- rng = period_range(start="2012-01-01", periods=10, freq="D")
- ts = Series(range(len(rng)), index=rng)
- exp = ts.iloc[[1]]
- tm.assert_series_equal(ts[[Period("2012-01-02", freq="D")]], exp)
- @pytest.mark.arm_slow
- def test_getitem_seconds(self):
- # GH#6716
- didx = date_range(start="2013/01/01 09:00:00", freq="S", periods=4000)
- pidx = period_range(start="2013/01/01 09:00:00", freq="S", periods=4000)
- for idx in [didx, pidx]:
- # getitem against index should raise ValueError
- values = [
- "2014",
- "2013/02",
- "2013/01/02",
- "2013/02/01 9H",
- "2013/02/01 09:00",
- ]
- for val in values:
- # GH7116
- # these show deprecations as we are trying
- # to slice with non-integer indexers
- with pytest.raises(IndexError, match="only integers, slices"):
- idx[val]
- ser = Series(np.random.rand(len(idx)), index=idx)
- tm.assert_series_equal(ser["2013/01/01 10:00"], ser[3600:3660])
- tm.assert_series_equal(ser["2013/01/01 9H"], ser[:3600])
- for d in ["2013/01/01", "2013/01", "2013"]:
- tm.assert_series_equal(ser[d], ser)
- @pytest.mark.parametrize(
- "idx_range",
- [
- date_range,
- period_range,
- ],
- )
- def test_getitem_day(self, idx_range):
- # GH#6716
- # Confirm DatetimeIndex and PeriodIndex works identically
- # getitem against index should raise ValueError
- idx = idx_range(start="2013/01/01", freq="D", periods=400)
- values = [
- "2014",
- "2013/02",
- "2013/01/02",
- "2013/02/01 9H",
- "2013/02/01 09:00",
- ]
- for val in values:
- # GH7116
- # these show deprecations as we are trying
- # to slice with non-integer indexers
- with pytest.raises(IndexError, match="only integers, slices"):
- idx[val]
- ser = Series(np.random.rand(len(idx)), index=idx)
- tm.assert_series_equal(ser["2013/01"], ser[0:31])
- tm.assert_series_equal(ser["2013/02"], ser[31:59])
- tm.assert_series_equal(ser["2014"], ser[365:])
- invalid = ["2013/02/01 9H", "2013/02/01 09:00"]
- for val in invalid:
- with pytest.raises(KeyError, match=val):
- ser[val]
- class TestGetLoc:
- def test_get_loc_msg(self):
- idx = period_range("2000-1-1", freq="A", periods=10)
- bad_period = Period("2012", "A")
- with pytest.raises(KeyError, match=r"^Period\('2012', 'A-DEC'\)$"):
- idx.get_loc(bad_period)
- try:
- idx.get_loc(bad_period)
- except KeyError as inst:
- assert inst.args[0] == bad_period
- def test_get_loc_nat(self):
- didx = DatetimeIndex(["2011-01-01", "NaT", "2011-01-03"])
- pidx = PeriodIndex(["2011-01-01", "NaT", "2011-01-03"], freq="M")
- # check DatetimeIndex compat
- for idx in [didx, pidx]:
- assert idx.get_loc(NaT) == 1
- assert idx.get_loc(None) == 1
- assert idx.get_loc(float("nan")) == 1
- assert idx.get_loc(np.nan) == 1
- def test_get_loc(self):
- # GH 17717
- p0 = Period("2017-09-01")
- p1 = Period("2017-09-02")
- p2 = Period("2017-09-03")
- # get the location of p1/p2 from
- # monotonic increasing PeriodIndex with non-duplicate
- idx0 = PeriodIndex([p0, p1, p2])
- expected_idx1_p1 = 1
- expected_idx1_p2 = 2
- assert idx0.get_loc(p1) == expected_idx1_p1
- assert idx0.get_loc(str(p1)) == expected_idx1_p1
- assert idx0.get_loc(p2) == expected_idx1_p2
- assert idx0.get_loc(str(p2)) == expected_idx1_p2
- msg = "Cannot interpret 'foo' as period"
- with pytest.raises(KeyError, match=msg):
- idx0.get_loc("foo")
- with pytest.raises(KeyError, match=r"^1\.1$"):
- idx0.get_loc(1.1)
- with pytest.raises(InvalidIndexError, match=re.escape(str(idx0))):
- idx0.get_loc(idx0)
- # get the location of p1/p2 from
- # monotonic increasing PeriodIndex with duplicate
- idx1 = PeriodIndex([p1, p1, p2])
- expected_idx1_p1 = slice(0, 2)
- expected_idx1_p2 = 2
- assert idx1.get_loc(p1) == expected_idx1_p1
- assert idx1.get_loc(str(p1)) == expected_idx1_p1
- assert idx1.get_loc(p2) == expected_idx1_p2
- assert idx1.get_loc(str(p2)) == expected_idx1_p2
- msg = "Cannot interpret 'foo' as period"
- with pytest.raises(KeyError, match=msg):
- idx1.get_loc("foo")
- with pytest.raises(KeyError, match=r"^1\.1$"):
- idx1.get_loc(1.1)
- with pytest.raises(InvalidIndexError, match=re.escape(str(idx1))):
- idx1.get_loc(idx1)
- # get the location of p1/p2 from
- # non-monotonic increasing/decreasing PeriodIndex with duplicate
- idx2 = PeriodIndex([p2, p1, p2])
- expected_idx2_p1 = 1
- expected_idx2_p2 = np.array([True, False, True])
- assert idx2.get_loc(p1) == expected_idx2_p1
- assert idx2.get_loc(str(p1)) == expected_idx2_p1
- tm.assert_numpy_array_equal(idx2.get_loc(p2), expected_idx2_p2)
- tm.assert_numpy_array_equal(idx2.get_loc(str(p2)), expected_idx2_p2)
- def test_get_loc_integer(self):
- dti = date_range("2016-01-01", periods=3)
- pi = dti.to_period("D")
- with pytest.raises(KeyError, match="16801"):
- pi.get_loc(16801)
- pi2 = dti.to_period("Y") # duplicates, ordinals are all 46
- with pytest.raises(KeyError, match="46"):
- pi2.get_loc(46)
- def test_get_loc_invalid_string_raises_keyerror(self):
- # GH#34240
- pi = period_range("2000", periods=3, name="A")
- with pytest.raises(KeyError, match="A"):
- pi.get_loc("A")
- ser = Series([1, 2, 3], index=pi)
- with pytest.raises(KeyError, match="A"):
- ser.loc["A"]
- with pytest.raises(KeyError, match="A"):
- ser["A"]
- assert "A" not in ser
- assert "A" not in pi
- def test_get_loc_mismatched_freq(self):
- # see also test_get_indexer_mismatched_dtype testing we get analogous
- # behavior for get_loc
- dti = date_range("2016-01-01", periods=3)
- pi = dti.to_period("D")
- pi2 = dti.to_period("W")
- pi3 = pi.view(pi2.dtype) # i.e. matching i8 representations
- with pytest.raises(KeyError, match="W-SUN"):
- pi.get_loc(pi2[0])
- with pytest.raises(KeyError, match="W-SUN"):
- # even though we have matching i8 values
- pi.get_loc(pi3[0])
- class TestGetIndexer:
- 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])
- tm.assert_numpy_array_equal(
- idx.get_indexer(idx), np.array([0, 1, 2], dtype=np.intp)
- )
- target = PeriodIndex([tp0, tp1, tp2, tp3])
- tm.assert_numpy_array_equal(
- idx.get_indexer(target, "pad"), np.array([-1, 0, 1, 2], dtype=np.intp)
- )
- tm.assert_numpy_array_equal(
- idx.get_indexer(target, "backfill"), np.array([0, 1, 2, -1], dtype=np.intp)
- )
- tm.assert_numpy_array_equal(
- idx.get_indexer(target, "nearest"), np.array([0, 0, 1, 2], dtype=np.intp)
- )
- res = idx.get_indexer(target, "nearest", tolerance=Timedelta("1 day"))
- tm.assert_numpy_array_equal(res, np.array([0, 0, 1, -1], dtype=np.intp))
- def test_get_indexer_mismatched_dtype(self):
- # Check that we return all -1s and do not raise or cast incorrectly
- dti = date_range("2016-01-01", periods=3)
- pi = dti.to_period("D")
- pi2 = dti.to_period("W")
- expected = np.array([-1, -1, -1], dtype=np.intp)
- result = pi.get_indexer(dti)
- tm.assert_numpy_array_equal(result, expected)
- # This should work in both directions
- result = dti.get_indexer(pi)
- tm.assert_numpy_array_equal(result, expected)
- result = pi.get_indexer(pi2)
- tm.assert_numpy_array_equal(result, expected)
- # We expect the same from get_indexer_non_unique
- result = pi.get_indexer_non_unique(dti)[0]
- tm.assert_numpy_array_equal(result, expected)
- result = dti.get_indexer_non_unique(pi)[0]
- tm.assert_numpy_array_equal(result, expected)
- result = pi.get_indexer_non_unique(pi2)[0]
- tm.assert_numpy_array_equal(result, expected)
- def test_get_indexer_mismatched_dtype_different_length(self, non_comparable_idx):
- # without method we aren't checking inequalities, so get all-missing
- # but do not raise
- dti = date_range("2016-01-01", periods=3)
- pi = dti.to_period("D")
- other = non_comparable_idx
- res = pi[:-1].get_indexer(other)
- expected = -np.ones(other.shape, dtype=np.intp)
- tm.assert_numpy_array_equal(res, expected)
- @pytest.mark.parametrize("method", ["pad", "backfill", "nearest"])
- def test_get_indexer_mismatched_dtype_with_method(self, non_comparable_idx, method):
- dti = date_range("2016-01-01", periods=3)
- pi = dti.to_period("D")
- other = non_comparable_idx
- msg = re.escape(f"Cannot compare dtypes {pi.dtype} and {other.dtype}")
- with pytest.raises(TypeError, match=msg):
- pi.get_indexer(other, method=method)
- for dtype in ["object", "category"]:
- other2 = other.astype(dtype)
- if dtype == "object" and isinstance(other, PeriodIndex):
- continue
- # Two different error message patterns depending on dtypes
- msg = "|".join(
- [
- re.escape(msg)
- for msg in (
- f"Cannot compare dtypes {pi.dtype} and {other.dtype}",
- " not supported between instances of ",
- )
- ]
- )
- with pytest.raises(TypeError, match=msg):
- pi.get_indexer(other2, method=method)
- def test_get_indexer_non_unique(self):
- # GH 17717
- p1 = Period("2017-09-02")
- p2 = Period("2017-09-03")
- p3 = Period("2017-09-04")
- p4 = Period("2017-09-05")
- idx1 = PeriodIndex([p1, p2, p1])
- idx2 = PeriodIndex([p2, p1, p3, p4])
- result = idx1.get_indexer_non_unique(idx2)
- expected_indexer = np.array([1, 0, 2, -1, -1], dtype=np.intp)
- expected_missing = np.array([2, 3], dtype=np.intp)
- 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_indexer2(self):
- idx = period_range("2000-01-01", periods=3).asfreq("H", how="start")
- tm.assert_numpy_array_equal(
- idx.get_indexer(idx), np.array([0, 1, 2], dtype=np.intp)
- )
- target = PeriodIndex(
- ["1999-12-31T23", "2000-01-01T12", "2000-01-02T01"], freq="H"
- )
- tm.assert_numpy_array_equal(
- idx.get_indexer(target, "pad"), np.array([-1, 0, 1], dtype=np.intp)
- )
- tm.assert_numpy_array_equal(
- idx.get_indexer(target, "backfill"), np.array([0, 1, 2], dtype=np.intp)
- )
- tm.assert_numpy_array_equal(
- idx.get_indexer(target, "nearest"), np.array([0, 1, 1], dtype=np.intp)
- )
- tm.assert_numpy_array_equal(
- idx.get_indexer(target, "nearest", tolerance="1 hour"),
- np.array([0, -1, 1], dtype=np.intp),
- )
- msg = "Input has different freq=None from PeriodArray\\(freq=H\\)"
- with pytest.raises(ValueError, match=msg):
- idx.get_indexer(target, "nearest", tolerance="1 minute")
- tm.assert_numpy_array_equal(
- idx.get_indexer(target, "nearest", tolerance="1 day"),
- np.array([0, 1, 1], dtype=np.intp),
- )
- tol_raw = [
- Timedelta("1 hour"),
- Timedelta("1 hour"),
- np.timedelta64(1, "D"),
- ]
- tm.assert_numpy_array_equal(
- idx.get_indexer(
- target, "nearest", tolerance=[np.timedelta64(x) for x in tol_raw]
- ),
- np.array([0, -1, 1], dtype=np.intp),
- )
- tol_bad = [
- Timedelta("2 hour").to_timedelta64(),
- Timedelta("1 hour").to_timedelta64(),
- np.timedelta64(1, "M"),
- ]
- with pytest.raises(
- libperiod.IncompatibleFrequency, match="Input has different freq=None from"
- ):
- idx.get_indexer(target, "nearest", tolerance=tol_bad)
- class TestWhere:
- def test_where(self, listlike_box):
- i = period_range("20130101", periods=5, freq="D")
- cond = [True] * len(i)
- expected = i
- result = i.where(listlike_box(cond))
- tm.assert_index_equal(result, expected)
- cond = [False] + [True] * (len(i) - 1)
- expected = PeriodIndex([NaT] + i[1:].tolist(), freq="D")
- result = i.where(listlike_box(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=arr)
- 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")
- tail = pi[2:].tolist()
- i2 = PeriodIndex([NaT, NaT] + tail, freq="D")
- mask = notna(i2)
- result = pi.where(mask, i2.asi8)
- expected = pd.Index([NaT._value, NaT._value] + tail, dtype=object)
- assert isinstance(expected[0], int)
- tm.assert_index_equal(result, expected)
- tdi = i2.asi8.view("timedelta64[ns]")
- expected = pd.Index([tdi[0], tdi[1]] + tail, dtype=object)
- assert isinstance(expected[0], np.timedelta64)
- result = pi.where(mask, tdi)
- tm.assert_index_equal(result, expected)
- dti = i2.to_timestamp("S")
- expected = pd.Index([dti[0], dti[1]] + tail, dtype=object)
- assert expected[0] is NaT
- result = pi.where(mask, dti)
- tm.assert_index_equal(result, expected)
- td = Timedelta(days=4)
- expected = pd.Index([td, td] + tail, dtype=object)
- assert expected[0] == td
- result = pi.where(mask, td)
- tm.assert_index_equal(result, expected)
- def test_where_mismatched_nat(self):
- pi = period_range("20130101", periods=5, freq="D")
- cond = np.array([True, False, True, True, False])
- tdnat = np.timedelta64("NaT", "ns")
- expected = pd.Index([pi[0], tdnat, pi[2], pi[3], tdnat], dtype=object)
- assert expected[1] is tdnat
- result = pi.where(cond, tdnat)
- tm.assert_index_equal(result, expected)
- 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:
- @pytest.mark.parametrize("freq", ["H", "D"])
- def test_get_value_datetime_hourly(self, freq):
- # get_loc and get_value should treat datetime objects symmetrically
- # TODO: this test used to test get_value, which is removed in 2.0.
- # should this test be moved somewhere, or is what's left redundant?
- dti = date_range("2016-01-01", periods=3, freq="MS")
- pi = dti.to_period(freq)
- ser = Series(range(7, 10), index=pi)
- ts = dti[0]
- assert pi.get_loc(ts) == 0
- 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"):
- ser[ts2]
- with pytest.raises(KeyError, match="2016-01-01 03:00"):
- ser.loc[ts2]
- else:
- assert pi.get_loc(ts2) == 0
- assert ser[ts2] == 7
- assert ser.loc[ts2] == 7
- 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)
- 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)
- assert "2017-09" in idx0
- assert p3 not in idx0
- def test_contains_freq_mismatch(self):
- rng = period_range("2007-01", freq="M", periods=10)
- assert Period("2007-01", freq="M") in rng
- assert Period("2007-01", freq="D") not in rng
- assert Period("2007-01", freq="2M") not in rng
- def test_contains_nat(self):
- # see gh-13582
- idx = period_range("2007-01", freq="M", periods=10)
- assert NaT not in idx
- assert None not in idx
- assert float("nan") not in idx
- assert np.nan not in idx
- idx = PeriodIndex(["2011-01", "NaT", "2011-02"], freq="M")
- assert NaT in idx
- assert None in idx
- assert float("nan") in idx
- assert np.nan in idx
- class TestAsOfLocs:
- def test_asof_locs_mismatched_type(self):
- dti = date_range("2016-01-01", periods=3)
- pi = dti.to_period("D")
- pi2 = dti.to_period("H")
- mask = np.array([0, 1, 0], dtype=bool)
- msg = "must be DatetimeIndex or PeriodIndex"
- with pytest.raises(TypeError, match=msg):
- pi.asof_locs(pd.Index(pi.asi8, dtype=np.int64), mask)
- with pytest.raises(TypeError, match=msg):
- pi.asof_locs(pd.Index(pi.asi8, dtype=np.float64), mask)
- with pytest.raises(TypeError, match=msg):
- # TimedeltaIndex
- pi.asof_locs(dti - dti, mask)
- msg = "Input has different freq=H"
- with pytest.raises(libperiod.IncompatibleFrequency, match=msg):
- pi.asof_locs(pi2, mask)
|