first commit

This commit is contained in:
Ayxan
2022-05-23 00:16:32 +04:00
commit d660f2a4ca
24786 changed files with 4428337 additions and 0 deletions

View File

@ -0,0 +1,130 @@
import pytest
from pandas import (
PeriodIndex,
period_range,
)
import pandas._testing as tm
class TestPeriodIndex:
def test_asfreq(self):
pi1 = period_range(freq="A", start="1/1/2001", end="1/1/2001")
pi2 = period_range(freq="Q", start="1/1/2001", end="1/1/2001")
pi3 = period_range(freq="M", start="1/1/2001", end="1/1/2001")
pi4 = period_range(freq="D", start="1/1/2001", end="1/1/2001")
pi5 = period_range(freq="H", start="1/1/2001", end="1/1/2001 00:00")
pi6 = period_range(freq="Min", start="1/1/2001", end="1/1/2001 00:00")
pi7 = period_range(freq="S", start="1/1/2001", end="1/1/2001 00:00:00")
assert pi1.asfreq("Q", "S") == pi2
assert pi1.asfreq("Q", "s") == pi2
assert pi1.asfreq("M", "start") == pi3
assert pi1.asfreq("D", "StarT") == pi4
assert pi1.asfreq("H", "beGIN") == pi5
assert pi1.asfreq("Min", "S") == pi6
assert pi1.asfreq("S", "S") == pi7
assert pi2.asfreq("A", "S") == pi1
assert pi2.asfreq("M", "S") == pi3
assert pi2.asfreq("D", "S") == pi4
assert pi2.asfreq("H", "S") == pi5
assert pi2.asfreq("Min", "S") == pi6
assert pi2.asfreq("S", "S") == pi7
assert pi3.asfreq("A", "S") == pi1
assert pi3.asfreq("Q", "S") == pi2
assert pi3.asfreq("D", "S") == pi4
assert pi3.asfreq("H", "S") == pi5
assert pi3.asfreq("Min", "S") == pi6
assert pi3.asfreq("S", "S") == pi7
assert pi4.asfreq("A", "S") == pi1
assert pi4.asfreq("Q", "S") == pi2
assert pi4.asfreq("M", "S") == pi3
assert pi4.asfreq("H", "S") == pi5
assert pi4.asfreq("Min", "S") == pi6
assert pi4.asfreq("S", "S") == pi7
assert pi5.asfreq("A", "S") == pi1
assert pi5.asfreq("Q", "S") == pi2
assert pi5.asfreq("M", "S") == pi3
assert pi5.asfreq("D", "S") == pi4
assert pi5.asfreq("Min", "S") == pi6
assert pi5.asfreq("S", "S") == pi7
assert pi6.asfreq("A", "S") == pi1
assert pi6.asfreq("Q", "S") == pi2
assert pi6.asfreq("M", "S") == pi3
assert pi6.asfreq("D", "S") == pi4
assert pi6.asfreq("H", "S") == pi5
assert pi6.asfreq("S", "S") == pi7
assert pi7.asfreq("A", "S") == pi1
assert pi7.asfreq("Q", "S") == pi2
assert pi7.asfreq("M", "S") == pi3
assert pi7.asfreq("D", "S") == pi4
assert pi7.asfreq("H", "S") == pi5
assert pi7.asfreq("Min", "S") == pi6
msg = "How must be one of S or E"
with pytest.raises(ValueError, match=msg):
pi7.asfreq("T", "foo")
result1 = pi1.asfreq("3M")
result2 = pi1.asfreq("M")
expected = period_range(freq="M", start="2001-12", end="2001-12")
tm.assert_numpy_array_equal(result1.asi8, expected.asi8)
assert result1.freqstr == "3M"
tm.assert_numpy_array_equal(result2.asi8, expected.asi8)
assert result2.freqstr == "M"
def test_asfreq_nat(self):
idx = PeriodIndex(["2011-01", "2011-02", "NaT", "2011-04"], freq="M")
result = idx.asfreq(freq="Q")
expected = PeriodIndex(["2011Q1", "2011Q1", "NaT", "2011Q2"], freq="Q")
tm.assert_index_equal(result, expected)
@pytest.mark.parametrize("freq", ["D", "3D"])
def test_asfreq_mult_pi(self, freq):
pi = PeriodIndex(["2001-01", "2001-02", "NaT", "2001-03"], freq="2M")
result = pi.asfreq(freq)
exp = PeriodIndex(["2001-02-28", "2001-03-31", "NaT", "2001-04-30"], freq=freq)
tm.assert_index_equal(result, exp)
assert result.freq == exp.freq
result = pi.asfreq(freq, how="S")
exp = PeriodIndex(["2001-01-01", "2001-02-01", "NaT", "2001-03-01"], freq=freq)
tm.assert_index_equal(result, exp)
assert result.freq == exp.freq
def test_asfreq_combined_pi(self):
pi = PeriodIndex(["2001-01-01 00:00", "2001-01-02 02:00", "NaT"], freq="H")
exp = PeriodIndex(["2001-01-01 00:00", "2001-01-02 02:00", "NaT"], freq="25H")
for freq, how in zip(["1D1H", "1H1D"], ["S", "E"]):
result = pi.asfreq(freq, how=how)
tm.assert_index_equal(result, exp)
assert result.freq == exp.freq
for freq in ["1D1H", "1H1D"]:
pi = PeriodIndex(["2001-01-01 00:00", "2001-01-02 02:00", "NaT"], freq=freq)
result = pi.asfreq("H")
exp = PeriodIndex(["2001-01-02 00:00", "2001-01-03 02:00", "NaT"], freq="H")
tm.assert_index_equal(result, exp)
assert result.freq == exp.freq
pi = PeriodIndex(["2001-01-01 00:00", "2001-01-02 02:00", "NaT"], freq=freq)
result = pi.asfreq("H", how="S")
exp = PeriodIndex(["2001-01-01 00:00", "2001-01-02 02:00", "NaT"], freq="H")
tm.assert_index_equal(result, exp)
assert result.freq == exp.freq
def test_astype_asfreq(self):
pi1 = PeriodIndex(["2011-01-01", "2011-02-01", "2011-03-01"], freq="D")
exp = PeriodIndex(["2011-01", "2011-02", "2011-03"], freq="M")
tm.assert_index_equal(pi1.asfreq("M"), exp)
tm.assert_index_equal(pi1.astype("period[M]"), exp)
exp = PeriodIndex(["2011-01", "2011-02", "2011-03"], freq="3M")
tm.assert_index_equal(pi1.asfreq("3M"), exp)
tm.assert_index_equal(pi1.astype("period[3M]"), exp)

View File

@ -0,0 +1,174 @@
import numpy as np
import pytest
from pandas import (
CategoricalIndex,
DatetimeIndex,
Index,
NaT,
Period,
PeriodIndex,
Timedelta,
period_range,
)
import pandas._testing as tm
from pandas.core.indexes.api import (
Int64Index,
UInt64Index,
)
class TestPeriodIndexAsType:
@pytest.mark.parametrize("dtype", [float, "timedelta64", "timedelta64[ns]"])
def test_astype_raises(self, dtype):
# GH#13149, GH#13209
idx = PeriodIndex(["2016-05-16", "NaT", NaT, np.NaN], freq="D")
msg = "Cannot cast PeriodIndex to dtype"
with pytest.raises(TypeError, match=msg):
idx.astype(dtype)
def test_astype_conversion(self):
# GH#13149, GH#13209
idx = PeriodIndex(["2016-05-16", "NaT", NaT, np.NaN], freq="D", name="idx")
result = idx.astype(object)
expected = Index(
[Period("2016-05-16", freq="D")] + [Period(NaT, freq="D")] * 3,
dtype="object",
name="idx",
)
tm.assert_index_equal(result, expected)
result = idx.astype(np.int64)
expected = Int64Index(
[16937] + [-9223372036854775808] * 3, dtype=np.int64, name="idx"
)
tm.assert_index_equal(result, expected)
result = idx.astype(str)
expected = Index([str(x) for x in idx], name="idx")
tm.assert_index_equal(result, expected)
idx = period_range("1990", "2009", freq="A", name="idx")
result = idx.astype("i8")
tm.assert_index_equal(result, Index(idx.asi8, name="idx"))
tm.assert_numpy_array_equal(result.values, idx.asi8)
def test_astype_uint(self):
arr = period_range("2000", periods=2, name="idx")
expected = UInt64Index(np.array([10957, 10958], dtype="uint64"), name="idx")
tm.assert_index_equal(arr.astype("uint64"), expected)
tm.assert_index_equal(arr.astype("uint32"), expected)
def test_astype_object(self):
idx = PeriodIndex([], freq="M")
exp = np.array([], dtype=object)
tm.assert_numpy_array_equal(idx.astype(object).values, exp)
tm.assert_numpy_array_equal(idx._mpl_repr(), exp)
idx = PeriodIndex(["2011-01", NaT], freq="M")
exp = np.array([Period("2011-01", freq="M"), NaT], dtype=object)
tm.assert_numpy_array_equal(idx.astype(object).values, exp)
tm.assert_numpy_array_equal(idx._mpl_repr(), exp)
exp = np.array([Period("2011-01-01", freq="D"), NaT], dtype=object)
idx = PeriodIndex(["2011-01-01", NaT], freq="D")
tm.assert_numpy_array_equal(idx.astype(object).values, exp)
tm.assert_numpy_array_equal(idx._mpl_repr(), exp)
# TODO: de-duplicate this version (from test_ops) with the one above
# (from test_period)
def test_astype_object2(self):
idx = period_range(start="2013-01-01", periods=4, freq="M", name="idx")
expected_list = [
Period("2013-01-31", freq="M"),
Period("2013-02-28", freq="M"),
Period("2013-03-31", freq="M"),
Period("2013-04-30", freq="M"),
]
expected = Index(expected_list, dtype=object, name="idx")
result = idx.astype(object)
assert isinstance(result, Index)
assert result.dtype == object
tm.assert_index_equal(result, expected)
assert result.name == expected.name
assert idx.tolist() == expected_list
idx = PeriodIndex(
["2013-01-01", "2013-01-02", "NaT", "2013-01-04"], freq="D", name="idx"
)
expected_list = [
Period("2013-01-01", freq="D"),
Period("2013-01-02", freq="D"),
Period("NaT", freq="D"),
Period("2013-01-04", freq="D"),
]
expected = Index(expected_list, dtype=object, name="idx")
result = idx.astype(object)
assert isinstance(result, Index)
assert result.dtype == object
tm.assert_index_equal(result, expected)
for i in [0, 1, 3]:
assert result[i] == expected[i]
assert result[2] is NaT
assert result.name == expected.name
result_list = idx.tolist()
for i in [0, 1, 3]:
assert result_list[i] == expected_list[i]
assert result_list[2] is NaT
def test_astype_category(self):
obj = period_range("2000", periods=2, name="idx")
result = obj.astype("category")
expected = CategoricalIndex(
[Period("2000-01-01", freq="D"), Period("2000-01-02", freq="D")], name="idx"
)
tm.assert_index_equal(result, expected)
result = obj._data.astype("category")
expected = expected.values
tm.assert_categorical_equal(result, expected)
def test_astype_array_fallback(self):
obj = period_range("2000", periods=2, name="idx")
result = obj.astype(bool)
expected = Index(np.array([True, True]), name="idx")
tm.assert_index_equal(result, expected)
result = obj._data.astype(bool)
expected = np.array([True, True])
tm.assert_numpy_array_equal(result, expected)
def test_period_astype_to_timestamp(self):
pi = PeriodIndex(["2011-01", "2011-02", "2011-03"], freq="M")
exp = DatetimeIndex(["2011-01-01", "2011-02-01", "2011-03-01"], freq="MS")
with tm.assert_produces_warning(FutureWarning):
# how keyword deprecated GH#37982
res = pi.astype("datetime64[ns]", how="start")
tm.assert_index_equal(res, exp)
assert res.freq == exp.freq
exp = DatetimeIndex(["2011-01-31", "2011-02-28", "2011-03-31"])
exp = exp + Timedelta(1, "D") - Timedelta(1, "ns")
with tm.assert_produces_warning(FutureWarning):
# how keyword deprecated GH#37982
res = pi.astype("datetime64[ns]", how="end")
tm.assert_index_equal(res, exp)
assert res.freq == exp.freq
exp = DatetimeIndex(["2011-01-01", "2011-02-01", "2011-03-01"], tz="US/Eastern")
res = pi.astype("datetime64[ns, US/Eastern]")
tm.assert_index_equal(res, exp)
assert res.freq == exp.freq
exp = DatetimeIndex(["2011-01-31", "2011-02-28", "2011-03-31"], tz="US/Eastern")
exp = exp + Timedelta(1, "D") - Timedelta(1, "ns")
with tm.assert_produces_warning(FutureWarning):
# how keyword deprecated GH#37982
res = pi.astype("datetime64[ns, US/Eastern]", how="end")
tm.assert_index_equal(res, exp)
assert res.freq == exp.freq

View File

@ -0,0 +1,52 @@
import numpy as np
from pandas import (
PeriodIndex,
factorize,
)
import pandas._testing as tm
class TestFactorize:
def test_factorize(self):
idx1 = PeriodIndex(
["2014-01", "2014-01", "2014-02", "2014-02", "2014-03", "2014-03"], freq="M"
)
exp_arr = np.array([0, 0, 1, 1, 2, 2], dtype=np.intp)
exp_idx = PeriodIndex(["2014-01", "2014-02", "2014-03"], freq="M")
arr, idx = idx1.factorize()
tm.assert_numpy_array_equal(arr, exp_arr)
tm.assert_index_equal(idx, exp_idx)
arr, idx = idx1.factorize(sort=True)
tm.assert_numpy_array_equal(arr, exp_arr)
tm.assert_index_equal(idx, exp_idx)
idx2 = PeriodIndex(
["2014-03", "2014-03", "2014-02", "2014-01", "2014-03", "2014-01"], freq="M"
)
exp_arr = np.array([2, 2, 1, 0, 2, 0], dtype=np.intp)
arr, idx = idx2.factorize(sort=True)
tm.assert_numpy_array_equal(arr, exp_arr)
tm.assert_index_equal(idx, exp_idx)
exp_arr = np.array([0, 0, 1, 2, 0, 2], dtype=np.intp)
exp_idx = PeriodIndex(["2014-03", "2014-02", "2014-01"], freq="M")
arr, idx = idx2.factorize()
tm.assert_numpy_array_equal(arr, exp_arr)
tm.assert_index_equal(idx, exp_idx)
def test_factorize_complex(self):
# GH 17927
array = [1, 2, 2 + 1j]
labels, uniques = factorize(array)
expected_labels = np.array([0, 1, 2], dtype=np.intp)
tm.assert_numpy_array_equal(labels, expected_labels)
# Should return a complex dtype in the future
expected_uniques = np.array([(1 + 0j), (2 + 0j), (2 + 1j)], dtype=object)
tm.assert_numpy_array_equal(uniques, expected_uniques)

View File

@ -0,0 +1,41 @@
from pandas import (
Index,
NaT,
Period,
PeriodIndex,
)
import pandas._testing as tm
class TestFillNA:
def test_fillna_period(self):
# GH#11343
idx = PeriodIndex(["2011-01-01 09:00", NaT, "2011-01-01 11:00"], freq="H")
exp = PeriodIndex(
["2011-01-01 09:00", "2011-01-01 10:00", "2011-01-01 11:00"], freq="H"
)
result = idx.fillna(Period("2011-01-01 10:00", freq="H"))
tm.assert_index_equal(result, exp)
exp = Index(
[
Period("2011-01-01 09:00", freq="H"),
"x",
Period("2011-01-01 11:00", freq="H"),
],
dtype=object,
)
result = idx.fillna("x")
tm.assert_index_equal(result, exp)
exp = Index(
[
Period("2011-01-01 09:00", freq="H"),
Period("2011-01-01", freq="D"),
Period("2011-01-01 11:00", freq="H"),
],
dtype=object,
)
result = idx.fillna(Period("2011-01-01", freq="D"))
tm.assert_index_equal(result, exp)

View File

@ -0,0 +1,18 @@
import numpy as np
import pytest
from pandas import (
NaT,
PeriodIndex,
period_range,
)
import pandas._testing as tm
class TestInsert:
@pytest.mark.parametrize("na", [np.nan, NaT, None])
def test_insert(self, na):
# GH#18295 (test missing)
expected = PeriodIndex(["2017Q1", NaT, "2017Q2", "2017Q3", "2017Q4"], freq="Q")
result = period_range("2017Q1", periods=4, freq="Q").insert(1, na)
tm.assert_index_equal(result, expected)

View File

@ -0,0 +1,23 @@
import pytest
from pandas import PeriodIndex
def test_is_full():
index = PeriodIndex([2005, 2007, 2009], freq="A")
assert not index.is_full
index = PeriodIndex([2005, 2006, 2007], freq="A")
assert index.is_full
index = PeriodIndex([2005, 2005, 2007], freq="A")
assert not index.is_full
index = PeriodIndex([2005, 2005, 2006], freq="A")
assert index.is_full
index = PeriodIndex([2006, 2005, 2005], freq="A")
with pytest.raises(ValueError, match="Index is not monotonic"):
index.is_full
assert index[:0].is_full

View File

@ -0,0 +1,26 @@
import numpy as np
import pytest
from pandas import (
PeriodIndex,
period_range,
)
import pandas._testing as tm
class TestRepeat:
@pytest.mark.parametrize("use_numpy", [True, False])
@pytest.mark.parametrize(
"index",
[
period_range("2000-01-01", periods=3, freq="D"),
period_range("2001-01-01", periods=3, freq="2D"),
PeriodIndex(["2001-01", "NaT", "2003-01"], freq="M"),
],
)
def test_repeat_freqstr(self, index, use_numpy):
# GH#10183
expected = PeriodIndex([per for per in index for _ in range(3)])
result = np.repeat(index, 3) if use_numpy else index.repeat(3)
tm.assert_index_equal(result, expected)
assert result.freqstr == index.freqstr

View File

@ -0,0 +1,122 @@
import numpy as np
import pytest
from pandas import (
PeriodIndex,
period_range,
)
import pandas._testing as tm
class TestPeriodIndexShift:
# ---------------------------------------------------------------
# PeriodIndex.shift is used by __add__ and __sub__
def test_pi_shift_ndarray(self):
idx = PeriodIndex(
["2011-01", "2011-02", "NaT", "2011-04"], freq="M", name="idx"
)
result = idx.shift(np.array([1, 2, 3, 4]))
expected = PeriodIndex(
["2011-02", "2011-04", "NaT", "2011-08"], freq="M", name="idx"
)
tm.assert_index_equal(result, expected)
result = idx.shift(np.array([1, -2, 3, -4]))
expected = PeriodIndex(
["2011-02", "2010-12", "NaT", "2010-12"], freq="M", name="idx"
)
tm.assert_index_equal(result, expected)
def test_shift(self):
pi1 = period_range(freq="A", start="1/1/2001", end="12/1/2009")
pi2 = period_range(freq="A", start="1/1/2002", end="12/1/2010")
tm.assert_index_equal(pi1.shift(0), pi1)
assert len(pi1) == len(pi2)
tm.assert_index_equal(pi1.shift(1), pi2)
pi1 = period_range(freq="A", start="1/1/2001", end="12/1/2009")
pi2 = period_range(freq="A", start="1/1/2000", end="12/1/2008")
assert len(pi1) == len(pi2)
tm.assert_index_equal(pi1.shift(-1), pi2)
pi1 = period_range(freq="M", start="1/1/2001", end="12/1/2009")
pi2 = period_range(freq="M", start="2/1/2001", end="1/1/2010")
assert len(pi1) == len(pi2)
tm.assert_index_equal(pi1.shift(1), pi2)
pi1 = period_range(freq="M", start="1/1/2001", end="12/1/2009")
pi2 = period_range(freq="M", start="12/1/2000", end="11/1/2009")
assert len(pi1) == len(pi2)
tm.assert_index_equal(pi1.shift(-1), pi2)
pi1 = period_range(freq="D", start="1/1/2001", end="12/1/2009")
pi2 = period_range(freq="D", start="1/2/2001", end="12/2/2009")
assert len(pi1) == len(pi2)
tm.assert_index_equal(pi1.shift(1), pi2)
pi1 = period_range(freq="D", start="1/1/2001", end="12/1/2009")
pi2 = period_range(freq="D", start="12/31/2000", end="11/30/2009")
assert len(pi1) == len(pi2)
tm.assert_index_equal(pi1.shift(-1), pi2)
def test_shift_corner_cases(self):
# GH#9903
idx = PeriodIndex([], name="xxx", freq="H")
msg = "`freq` argument is not supported for PeriodArray._time_shift"
with pytest.raises(TypeError, match=msg):
# period shift doesn't accept freq
idx.shift(1, freq="H")
tm.assert_index_equal(idx.shift(0), idx)
tm.assert_index_equal(idx.shift(3), idx)
idx = PeriodIndex(
["2011-01-01 10:00", "2011-01-01 11:00", "2011-01-01 12:00"],
name="xxx",
freq="H",
)
tm.assert_index_equal(idx.shift(0), idx)
exp = PeriodIndex(
["2011-01-01 13:00", "2011-01-01 14:00", "2011-01-01 15:00"],
name="xxx",
freq="H",
)
tm.assert_index_equal(idx.shift(3), exp)
exp = PeriodIndex(
["2011-01-01 07:00", "2011-01-01 08:00", "2011-01-01 09:00"],
name="xxx",
freq="H",
)
tm.assert_index_equal(idx.shift(-3), exp)
def test_shift_nat(self):
idx = PeriodIndex(
["2011-01", "2011-02", "NaT", "2011-04"], freq="M", name="idx"
)
result = idx.shift(1)
expected = PeriodIndex(
["2011-02", "2011-03", "NaT", "2011-05"], freq="M", name="idx"
)
tm.assert_index_equal(result, expected)
assert result.name == expected.name
def test_shift_gh8083(self):
# test shift for PeriodIndex
# GH#8083
drange = period_range("20130101", periods=5, freq="D")
result = drange.shift(1)
expected = PeriodIndex(
["2013-01-02", "2013-01-03", "2013-01-04", "2013-01-05", "2013-01-06"],
freq="D",
)
tm.assert_index_equal(result, expected)
def test_shift_periods(self):
# GH #22458 : argument 'n' was deprecated in favor of 'periods'
idx = period_range(freq="A", start="1/1/2001", end="12/1/2009")
tm.assert_index_equal(idx.shift(periods=0), idx)
tm.assert_index_equal(idx.shift(0), idx)

View File

@ -0,0 +1,132 @@
from datetime import datetime
import numpy as np
import pytest
from pandas import (
DatetimeIndex,
NaT,
PeriodIndex,
Timedelta,
Timestamp,
date_range,
period_range,
)
import pandas._testing as tm
class TestToTimestamp:
def test_to_timestamp_non_contiguous(self):
# GH#44100
dti = date_range("2021-10-18", periods=9, freq="B")
pi = dti.to_period()
result = pi[::2].to_timestamp()
expected = dti[::2]
tm.assert_index_equal(result, expected)
result = pi._data[::2].to_timestamp()
expected = dti._data[::2]
# TODO: can we get the freq to round-trip?
tm.assert_datetime_array_equal(result, expected, check_freq=False)
result = pi[::-1].to_timestamp()
expected = dti[::-1]
tm.assert_index_equal(result, expected)
result = pi._data[::-1].to_timestamp()
expected = dti._data[::-1]
tm.assert_datetime_array_equal(result, expected, check_freq=False)
result = pi[::2][::-1].to_timestamp()
expected = dti[::2][::-1]
tm.assert_index_equal(result, expected)
result = pi._data[::2][::-1].to_timestamp()
expected = dti._data[::2][::-1]
tm.assert_datetime_array_equal(result, expected, check_freq=False)
def test_to_timestamp_freq(self):
idx = period_range("2017", periods=12, freq="A-DEC")
result = idx.to_timestamp()
expected = date_range("2017", periods=12, freq="AS-JAN")
tm.assert_index_equal(result, expected)
def test_to_timestamp_pi_nat(self):
# GH#7228
index = PeriodIndex(["NaT", "2011-01", "2011-02"], freq="M", name="idx")
result = index.to_timestamp("D")
expected = DatetimeIndex(
[NaT, datetime(2011, 1, 1), datetime(2011, 2, 1)], name="idx"
)
tm.assert_index_equal(result, expected)
assert result.name == "idx"
result2 = result.to_period(freq="M")
tm.assert_index_equal(result2, index)
assert result2.name == "idx"
result3 = result.to_period(freq="3M")
exp = PeriodIndex(["NaT", "2011-01", "2011-02"], freq="3M", name="idx")
tm.assert_index_equal(result3, exp)
assert result3.freqstr == "3M"
msg = "Frequency must be positive, because it represents span: -2A"
with pytest.raises(ValueError, match=msg):
result.to_period(freq="-2A")
def test_to_timestamp_preserve_name(self):
index = period_range(freq="A", start="1/1/2001", end="12/1/2009", name="foo")
assert index.name == "foo"
conv = index.to_timestamp("D")
assert conv.name == "foo"
def test_to_timestamp_quarterly_bug(self):
years = np.arange(1960, 2000).repeat(4)
quarters = np.tile(list(range(1, 5)), 40)
pindex = PeriodIndex(year=years, quarter=quarters)
stamps = pindex.to_timestamp("D", "end")
expected = DatetimeIndex([x.to_timestamp("D", "end") for x in pindex])
tm.assert_index_equal(stamps, expected)
assert stamps.freq == expected.freq
def test_to_timestamp_pi_mult(self):
idx = PeriodIndex(["2011-01", "NaT", "2011-02"], freq="2M", name="idx")
result = idx.to_timestamp()
expected = DatetimeIndex(["2011-01-01", "NaT", "2011-02-01"], name="idx")
tm.assert_index_equal(result, expected)
result = idx.to_timestamp(how="E")
expected = DatetimeIndex(["2011-02-28", "NaT", "2011-03-31"], name="idx")
expected = expected + Timedelta(1, "D") - Timedelta(1, "ns")
tm.assert_index_equal(result, expected)
def test_to_timestamp_pi_combined(self):
idx = period_range(start="2011", periods=2, freq="1D1H", name="idx")
result = idx.to_timestamp()
expected = DatetimeIndex(["2011-01-01 00:00", "2011-01-02 01:00"], name="idx")
tm.assert_index_equal(result, expected)
result = idx.to_timestamp(how="E")
expected = DatetimeIndex(
["2011-01-02 00:59:59", "2011-01-03 01:59:59"], name="idx"
)
expected = expected + Timedelta(1, "s") - Timedelta(1, "ns")
tm.assert_index_equal(result, expected)
result = idx.to_timestamp(how="E", freq="H")
expected = DatetimeIndex(["2011-01-02 00:00", "2011-01-03 01:00"], name="idx")
expected = expected + Timedelta(1, "h") - Timedelta(1, "ns")
tm.assert_index_equal(result, expected)
def test_to_timestamp_1703(self):
index = period_range("1/1/2012", periods=4, freq="D")
result = index.to_timestamp()
assert result[0] == Timestamp("1/1/2012")

View File

@ -0,0 +1,548 @@
import numpy as np
import pytest
from pandas._libs.tslibs.period import IncompatibleFrequency
from pandas.core.dtypes.dtypes import PeriodDtype
from pandas import (
Index,
NaT,
Period,
PeriodIndex,
Series,
date_range,
offsets,
period_range,
)
import pandas._testing as tm
from pandas.core.arrays import PeriodArray
class TestPeriodIndex:
def test_construction_base_constructor(self):
# GH 13664
arr = [Period("2011-01", freq="M"), NaT, Period("2011-03", freq="M")]
tm.assert_index_equal(Index(arr), PeriodIndex(arr))
tm.assert_index_equal(Index(np.array(arr)), PeriodIndex(np.array(arr)))
arr = [np.nan, NaT, Period("2011-03", freq="M")]
tm.assert_index_equal(Index(arr), PeriodIndex(arr))
tm.assert_index_equal(Index(np.array(arr)), PeriodIndex(np.array(arr)))
arr = [Period("2011-01", freq="M"), NaT, Period("2011-03", freq="D")]
tm.assert_index_equal(Index(arr), Index(arr, dtype=object))
tm.assert_index_equal(Index(np.array(arr)), Index(np.array(arr), dtype=object))
def test_base_constructor_with_period_dtype(self):
dtype = PeriodDtype("D")
values = ["2011-01-01", "2012-03-04", "2014-05-01"]
result = Index(values, dtype=dtype)
expected = PeriodIndex(values, dtype=dtype)
tm.assert_index_equal(result, expected)
@pytest.mark.parametrize(
"values_constructor", [list, np.array, PeriodIndex, PeriodArray._from_sequence]
)
def test_index_object_dtype(self, values_constructor):
# Index(periods, dtype=object) is an Index (not an PeriodIndex)
periods = [
Period("2011-01", freq="M"),
NaT,
Period("2011-03", freq="M"),
]
values = values_constructor(periods)
result = Index(values, dtype=object)
assert type(result) is Index
tm.assert_numpy_array_equal(result.values, np.array(values))
def test_constructor_use_start_freq(self):
# GH #1118
p = Period("4/2/2012", freq="B")
expected = period_range(start="4/2/2012", periods=10, freq="B")
index = period_range(start=p, periods=10)
tm.assert_index_equal(index, expected)
def test_constructor_field_arrays(self):
# GH #1264
years = np.arange(1990, 2010).repeat(4)[2:-2]
quarters = np.tile(np.arange(1, 5), 20)[2:-2]
index = PeriodIndex(year=years, quarter=quarters, freq="Q-DEC")
expected = period_range("1990Q3", "2009Q2", freq="Q-DEC")
tm.assert_index_equal(index, expected)
index2 = PeriodIndex(year=years, quarter=quarters, freq="2Q-DEC")
tm.assert_numpy_array_equal(index.asi8, index2.asi8)
index = PeriodIndex(year=years, quarter=quarters)
tm.assert_index_equal(index, expected)
years = [2007, 2007, 2007]
months = [1, 2]
msg = "Mismatched Period array lengths"
with pytest.raises(ValueError, match=msg):
PeriodIndex(year=years, month=months, freq="M")
with pytest.raises(ValueError, match=msg):
PeriodIndex(year=years, month=months, freq="2M")
years = [2007, 2007, 2007]
months = [1, 2, 3]
idx = PeriodIndex(year=years, month=months, freq="M")
exp = period_range("2007-01", periods=3, freq="M")
tm.assert_index_equal(idx, exp)
def test_constructor_U(self):
# U was used as undefined period
with pytest.raises(ValueError, match="Invalid frequency: X"):
period_range("2007-1-1", periods=500, freq="X")
def test_constructor_nano(self):
idx = period_range(
start=Period(ordinal=1, freq="N"), end=Period(ordinal=4, freq="N"), freq="N"
)
exp = PeriodIndex(
[
Period(ordinal=1, freq="N"),
Period(ordinal=2, freq="N"),
Period(ordinal=3, freq="N"),
Period(ordinal=4, freq="N"),
],
freq="N",
)
tm.assert_index_equal(idx, exp)
def test_constructor_arrays_negative_year(self):
years = np.arange(1960, 2000, dtype=np.int64).repeat(4)
quarters = np.tile(np.array([1, 2, 3, 4], dtype=np.int64), 40)
pindex = PeriodIndex(year=years, quarter=quarters)
tm.assert_index_equal(pindex.year, Index(years))
tm.assert_index_equal(pindex.quarter, Index(quarters))
def test_constructor_invalid_quarters(self):
msg = "Quarter must be 1 <= q <= 4"
with pytest.raises(ValueError, match=msg):
PeriodIndex(year=range(2000, 2004), quarter=list(range(4)), freq="Q-DEC")
def test_constructor_corner(self):
result = period_range("2007-01", periods=10.5, freq="M")
exp = period_range("2007-01", periods=10, freq="M")
tm.assert_index_equal(result, exp)
def test_constructor_fromarraylike(self):
idx = period_range("2007-01", periods=20, freq="M")
# values is an array of Period, thus can retrieve freq
tm.assert_index_equal(PeriodIndex(idx.values), idx)
tm.assert_index_equal(PeriodIndex(list(idx.values)), idx)
msg = "freq not specified and cannot be inferred"
with pytest.raises(ValueError, match=msg):
PeriodIndex(idx.asi8)
with pytest.raises(ValueError, match=msg):
PeriodIndex(list(idx.asi8))
msg = "'Period' object is not iterable"
with pytest.raises(TypeError, match=msg):
PeriodIndex(data=Period("2007", freq="A"))
result = PeriodIndex(iter(idx))
tm.assert_index_equal(result, idx)
result = PeriodIndex(idx)
tm.assert_index_equal(result, idx)
result = PeriodIndex(idx, freq="M")
tm.assert_index_equal(result, idx)
result = PeriodIndex(idx, freq=offsets.MonthEnd())
tm.assert_index_equal(result, idx)
assert result.freq == "M"
result = PeriodIndex(idx, freq="2M")
tm.assert_index_equal(result, idx.asfreq("2M"))
assert result.freq == "2M"
result = PeriodIndex(idx, freq=offsets.MonthEnd(2))
tm.assert_index_equal(result, idx.asfreq("2M"))
assert result.freq == "2M"
result = PeriodIndex(idx, freq="D")
exp = idx.asfreq("D", "e")
tm.assert_index_equal(result, exp)
def test_constructor_datetime64arr(self):
vals = np.arange(100000, 100000 + 10000, 100, dtype=np.int64)
vals = vals.view(np.dtype("M8[us]"))
msg = r"Wrong dtype: datetime64\[us\]"
with pytest.raises(ValueError, match=msg):
PeriodIndex(vals, freq="D")
@pytest.mark.parametrize("box", [None, "series", "index"])
def test_constructor_datetime64arr_ok(self, box):
# https://github.com/pandas-dev/pandas/issues/23438
data = date_range("2017", periods=4, freq="M")
if box is None:
data = data._values
elif box == "series":
data = Series(data)
result = PeriodIndex(data, freq="D")
expected = PeriodIndex(
["2017-01-31", "2017-02-28", "2017-03-31", "2017-04-30"], freq="D"
)
tm.assert_index_equal(result, expected)
def test_constructor_dtype(self):
# passing a dtype with a tz should localize
idx = PeriodIndex(["2013-01", "2013-03"], dtype="period[M]")
exp = PeriodIndex(["2013-01", "2013-03"], freq="M")
tm.assert_index_equal(idx, exp)
assert idx.dtype == "period[M]"
idx = PeriodIndex(["2013-01-05", "2013-03-05"], dtype="period[3D]")
exp = PeriodIndex(["2013-01-05", "2013-03-05"], freq="3D")
tm.assert_index_equal(idx, exp)
assert idx.dtype == "period[3D]"
# if we already have a freq and its not the same, then asfreq
# (not changed)
idx = PeriodIndex(["2013-01-01", "2013-01-02"], freq="D")
res = PeriodIndex(idx, dtype="period[M]")
exp = PeriodIndex(["2013-01", "2013-01"], freq="M")
tm.assert_index_equal(res, exp)
assert res.dtype == "period[M]"
res = PeriodIndex(idx, freq="M")
tm.assert_index_equal(res, exp)
assert res.dtype == "period[M]"
msg = "specified freq and dtype are different"
with pytest.raises(IncompatibleFrequency, match=msg):
PeriodIndex(["2011-01"], freq="M", dtype="period[D]")
def test_constructor_empty(self):
idx = PeriodIndex([], freq="M")
assert isinstance(idx, PeriodIndex)
assert len(idx) == 0
assert idx.freq == "M"
with pytest.raises(ValueError, match="freq not specified"):
PeriodIndex([])
def test_constructor_pi_nat(self):
idx = PeriodIndex(
[Period("2011-01", freq="M"), NaT, Period("2011-01", freq="M")]
)
exp = PeriodIndex(["2011-01", "NaT", "2011-01"], freq="M")
tm.assert_index_equal(idx, exp)
idx = PeriodIndex(
np.array([Period("2011-01", freq="M"), NaT, Period("2011-01", freq="M")])
)
tm.assert_index_equal(idx, exp)
idx = PeriodIndex(
[NaT, NaT, Period("2011-01", freq="M"), Period("2011-01", freq="M")]
)
exp = PeriodIndex(["NaT", "NaT", "2011-01", "2011-01"], freq="M")
tm.assert_index_equal(idx, exp)
idx = PeriodIndex(
np.array(
[NaT, NaT, Period("2011-01", freq="M"), Period("2011-01", freq="M")]
)
)
tm.assert_index_equal(idx, exp)
idx = PeriodIndex([NaT, NaT, "2011-01", "2011-01"], freq="M")
tm.assert_index_equal(idx, exp)
with pytest.raises(ValueError, match="freq not specified"):
PeriodIndex([NaT, NaT])
with pytest.raises(ValueError, match="freq not specified"):
PeriodIndex(np.array([NaT, NaT]))
with pytest.raises(ValueError, match="freq not specified"):
PeriodIndex(["NaT", "NaT"])
with pytest.raises(ValueError, match="freq not specified"):
PeriodIndex(np.array(["NaT", "NaT"]))
def test_constructor_incompat_freq(self):
msg = "Input has different freq=D from PeriodIndex\\(freq=M\\)"
with pytest.raises(IncompatibleFrequency, match=msg):
PeriodIndex([Period("2011-01", freq="M"), NaT, Period("2011-01", freq="D")])
with pytest.raises(IncompatibleFrequency, match=msg):
PeriodIndex(
np.array(
[Period("2011-01", freq="M"), NaT, Period("2011-01", freq="D")]
)
)
# first element is NaT
with pytest.raises(IncompatibleFrequency, match=msg):
PeriodIndex([NaT, Period("2011-01", freq="M"), Period("2011-01", freq="D")])
with pytest.raises(IncompatibleFrequency, match=msg):
PeriodIndex(
np.array(
[NaT, Period("2011-01", freq="M"), Period("2011-01", freq="D")]
)
)
def test_constructor_mixed(self):
idx = PeriodIndex(["2011-01", NaT, Period("2011-01", freq="M")])
exp = PeriodIndex(["2011-01", "NaT", "2011-01"], freq="M")
tm.assert_index_equal(idx, exp)
idx = PeriodIndex(["NaT", NaT, Period("2011-01", freq="M")])
exp = PeriodIndex(["NaT", "NaT", "2011-01"], freq="M")
tm.assert_index_equal(idx, exp)
idx = PeriodIndex([Period("2011-01-01", freq="D"), NaT, "2012-01-01"])
exp = PeriodIndex(["2011-01-01", "NaT", "2012-01-01"], freq="D")
tm.assert_index_equal(idx, exp)
def test_constructor_simple_new(self):
idx = period_range("2007-01", name="p", periods=2, freq="M")
with pytest.raises(AssertionError, match="<class .*PeriodIndex'>"):
idx._simple_new(idx, name="p")
result = idx._simple_new(idx._data, name="p")
tm.assert_index_equal(result, idx)
msg = "Should be numpy array of type i8"
with pytest.raises(AssertionError, match=msg):
# Need ndarray, not Int64Index
type(idx._data)._simple_new(Index(idx.asi8), freq=idx.freq)
arr = type(idx._data)._simple_new(idx.asi8, freq=idx.freq)
result = idx._simple_new(arr, name="p")
tm.assert_index_equal(result, idx)
def test_constructor_simple_new_empty(self):
# GH13079
idx = PeriodIndex([], freq="M", name="p")
with pytest.raises(AssertionError, match="<class .*PeriodIndex'>"):
idx._simple_new(idx, name="p")
result = idx._simple_new(idx._data, name="p")
tm.assert_index_equal(result, idx)
@pytest.mark.parametrize("floats", [[1.1, 2.1], np.array([1.1, 2.1])])
def test_constructor_floats(self, floats):
with pytest.raises(AssertionError, match="<class "):
PeriodIndex._simple_new(floats)
msg = "PeriodIndex does not allow floating point in construction"
with pytest.raises(TypeError, match=msg):
PeriodIndex(floats)
def test_constructor_nat(self):
msg = "start and end must not be NaT"
with pytest.raises(ValueError, match=msg):
period_range(start="NaT", end="2011-01-01", freq="M")
with pytest.raises(ValueError, match=msg):
period_range(start="2011-01-01", end="NaT", freq="M")
def test_constructor_year_and_quarter(self):
year = Series([2001, 2002, 2003])
quarter = year - 2000
idx = PeriodIndex(year=year, quarter=quarter)
strs = [f"{t[0]:d}Q{t[1]:d}" for t in zip(quarter, year)]
lops = list(map(Period, strs))
p = PeriodIndex(lops)
tm.assert_index_equal(p, idx)
def test_constructor_freq_mult(self):
# GH #7811
pidx = period_range(start="2014-01", freq="2M", periods=4)
expected = PeriodIndex(["2014-01", "2014-03", "2014-05", "2014-07"], freq="2M")
tm.assert_index_equal(pidx, expected)
pidx = period_range(start="2014-01-02", end="2014-01-15", freq="3D")
expected = PeriodIndex(
["2014-01-02", "2014-01-05", "2014-01-08", "2014-01-11", "2014-01-14"],
freq="3D",
)
tm.assert_index_equal(pidx, expected)
pidx = period_range(end="2014-01-01 17:00", freq="4H", periods=3)
expected = PeriodIndex(
["2014-01-01 09:00", "2014-01-01 13:00", "2014-01-01 17:00"], freq="4H"
)
tm.assert_index_equal(pidx, expected)
msg = "Frequency must be positive, because it represents span: -1M"
with pytest.raises(ValueError, match=msg):
PeriodIndex(["2011-01"], freq="-1M")
msg = "Frequency must be positive, because it represents span: 0M"
with pytest.raises(ValueError, match=msg):
PeriodIndex(["2011-01"], freq="0M")
msg = "Frequency must be positive, because it represents span: 0M"
with pytest.raises(ValueError, match=msg):
period_range("2011-01", periods=3, freq="0M")
@pytest.mark.parametrize("freq", ["A", "M", "D", "T", "S"])
@pytest.mark.parametrize("mult", [1, 2, 3, 4, 5])
def test_constructor_freq_mult_dti_compat(self, mult, freq):
freqstr = str(mult) + freq
pidx = period_range(start="2014-04-01", freq=freqstr, periods=10)
expected = date_range(start="2014-04-01", freq=freqstr, periods=10).to_period(
freqstr
)
tm.assert_index_equal(pidx, expected)
def test_constructor_freq_combined(self):
for freq in ["1D1H", "1H1D"]:
pidx = PeriodIndex(["2016-01-01", "2016-01-02"], freq=freq)
expected = PeriodIndex(["2016-01-01 00:00", "2016-01-02 00:00"], freq="25H")
for freq in ["1D1H", "1H1D"]:
pidx = period_range(start="2016-01-01", periods=2, freq=freq)
expected = PeriodIndex(["2016-01-01 00:00", "2016-01-02 01:00"], freq="25H")
tm.assert_index_equal(pidx, expected)
def test_constructor(self):
pi = period_range(freq="A", start="1/1/2001", end="12/1/2009")
assert len(pi) == 9
pi = period_range(freq="Q", start="1/1/2001", end="12/1/2009")
assert len(pi) == 4 * 9
pi = period_range(freq="M", start="1/1/2001", end="12/1/2009")
assert len(pi) == 12 * 9
pi = period_range(freq="D", start="1/1/2001", end="12/31/2009")
assert len(pi) == 365 * 9 + 2
pi = period_range(freq="B", start="1/1/2001", end="12/31/2009")
assert len(pi) == 261 * 9
pi = period_range(freq="H", start="1/1/2001", end="12/31/2001 23:00")
assert len(pi) == 365 * 24
pi = period_range(freq="Min", start="1/1/2001", end="1/1/2001 23:59")
assert len(pi) == 24 * 60
pi = period_range(freq="S", start="1/1/2001", end="1/1/2001 23:59:59")
assert len(pi) == 24 * 60 * 60
start = Period("02-Apr-2005", "B")
i1 = period_range(start=start, periods=20)
assert len(i1) == 20
assert i1.freq == start.freq
assert i1[0] == start
end_intv = Period("2006-12-31", "W")
i1 = period_range(end=end_intv, periods=10)
assert len(i1) == 10
assert i1.freq == end_intv.freq
assert i1[-1] == end_intv
end_intv = Period("2006-12-31", "1w")
i2 = period_range(end=end_intv, periods=10)
assert len(i1) == len(i2)
assert (i1 == i2).all()
assert i1.freq == i2.freq
end_intv = Period("2005-05-01", "B")
i1 = period_range(start=start, end=end_intv)
# infer freq from first element
i2 = PeriodIndex([end_intv, Period("2005-05-05", "B")])
assert len(i2) == 2
assert i2[0] == end_intv
i2 = PeriodIndex(np.array([end_intv, Period("2005-05-05", "B")]))
assert len(i2) == 2
assert i2[0] == end_intv
# Mixed freq should fail
vals = [end_intv, Period("2006-12-31", "w")]
msg = r"Input has different freq=W-SUN from PeriodIndex\(freq=B\)"
with pytest.raises(IncompatibleFrequency, match=msg):
PeriodIndex(vals)
vals = np.array(vals)
with pytest.raises(IncompatibleFrequency, match=msg):
PeriodIndex(vals)
# tuple freq disallowed GH#34703
with pytest.raises(TypeError, match="pass as a string instead"):
Period("2006-12-31", ("w", 1))
@pytest.mark.parametrize(
"freq", ["M", "Q", "A", "D", "B", "T", "S", "L", "U", "N", "H"]
)
def test_recreate_from_data(self, freq):
org = period_range(start="2001/04/01", freq=freq, periods=1)
idx = PeriodIndex(org.values, freq=freq)
tm.assert_index_equal(idx, org)
def test_map_with_string_constructor(self):
raw = [2005, 2007, 2009]
index = PeriodIndex(raw, freq="A")
expected = Index([str(num) for num in raw])
res = index.map(str)
# should return an Index
assert isinstance(res, Index)
# preserve element types
assert all(isinstance(resi, str) for resi in res)
# lastly, values should compare equal
tm.assert_index_equal(res, expected)
class TestShallowCopy:
def test_shallow_copy_empty(self):
# GH#13067
idx = PeriodIndex([], freq="M")
result = idx._view()
expected = idx
tm.assert_index_equal(result, expected)
def test_shallow_copy_disallow_i8(self):
# GH#24391
pi = period_range("2018-01-01", periods=3, freq="2D")
with pytest.raises(AssertionError, match="ndarray"):
pi._shallow_copy(pi.asi8)
def test_shallow_copy_requires_disallow_period_index(self):
pi = period_range("2018-01-01", periods=3, freq="2D")
with pytest.raises(AssertionError, match="PeriodIndex"):
pi._shallow_copy(pi)
class TestSeriesPeriod:
def setup_method(self, method):
self.series = Series(period_range("2000-01-01", periods=10, freq="D"))
def test_constructor_cant_cast_period(self):
msg = "Cannot cast PeriodIndex to dtype float64"
with pytest.raises(TypeError, match=msg):
Series(period_range("2000-01-01", periods=10, freq="D"), dtype=float)
def test_constructor_cast_object(self):
s = Series(period_range("1/1/2000", periods=10), dtype=PeriodDtype("D"))
exp = Series(period_range("1/1/2000", periods=10))
tm.assert_series_equal(s, exp)

View File

@ -0,0 +1,199 @@
import numpy as np
import pytest
import pandas as pd
from pandas import (
PeriodIndex,
Series,
)
import pandas._testing as tm
def test_to_native_types():
index = PeriodIndex(["2017-01-01", "2017-01-02", "2017-01-03"], freq="D")
# First, with no arguments.
expected = np.array(["2017-01-01", "2017-01-02", "2017-01-03"], dtype="=U10")
result = index._format_native_types()
tm.assert_numpy_array_equal(result, expected)
# No NaN values, so na_rep has no effect
result = index._format_native_types(na_rep="pandas")
tm.assert_numpy_array_equal(result, expected)
# Make sure date formatting works
expected = np.array(["01-2017-01", "01-2017-02", "01-2017-03"], dtype="=U10")
result = index._format_native_types(date_format="%m-%Y-%d")
tm.assert_numpy_array_equal(result, expected)
# NULL object handling should work
index = PeriodIndex(["2017-01-01", pd.NaT, "2017-01-03"], freq="D")
expected = np.array(["2017-01-01", "NaT", "2017-01-03"], dtype=object)
result = index._format_native_types()
tm.assert_numpy_array_equal(result, expected)
expected = np.array(["2017-01-01", "pandas", "2017-01-03"], dtype=object)
result = index._format_native_types(na_rep="pandas")
tm.assert_numpy_array_equal(result, expected)
class TestPeriodIndexRendering:
def test_frame_repr(self):
df = pd.DataFrame({"A": [1, 2, 3]}, index=pd.date_range("2000", periods=3))
result = repr(df)
expected = " A\n2000-01-01 1\n2000-01-02 2\n2000-01-03 3"
assert result == expected
@pytest.mark.parametrize("method", ["__repr__", "__str__"])
def test_representation(self, method):
# GH#7601
idx1 = PeriodIndex([], freq="D")
idx2 = PeriodIndex(["2011-01-01"], freq="D")
idx3 = PeriodIndex(["2011-01-01", "2011-01-02"], freq="D")
idx4 = PeriodIndex(["2011-01-01", "2011-01-02", "2011-01-03"], freq="D")
idx5 = PeriodIndex(["2011", "2012", "2013"], freq="A")
idx6 = PeriodIndex(["2011-01-01 09:00", "2012-02-01 10:00", "NaT"], freq="H")
idx7 = pd.period_range("2013Q1", periods=1, freq="Q")
idx8 = pd.period_range("2013Q1", periods=2, freq="Q")
idx9 = pd.period_range("2013Q1", periods=3, freq="Q")
idx10 = PeriodIndex(["2011-01-01", "2011-02-01"], freq="3D")
exp1 = "PeriodIndex([], dtype='period[D]')"
exp2 = "PeriodIndex(['2011-01-01'], dtype='period[D]')"
exp3 = "PeriodIndex(['2011-01-01', '2011-01-02'], dtype='period[D]')"
exp4 = (
"PeriodIndex(['2011-01-01', '2011-01-02', '2011-01-03'], "
"dtype='period[D]')"
)
exp5 = "PeriodIndex(['2011', '2012', '2013'], dtype='period[A-DEC]')"
exp6 = (
"PeriodIndex(['2011-01-01 09:00', '2012-02-01 10:00', 'NaT'], "
"dtype='period[H]')"
)
exp7 = "PeriodIndex(['2013Q1'], dtype='period[Q-DEC]')"
exp8 = "PeriodIndex(['2013Q1', '2013Q2'], dtype='period[Q-DEC]')"
exp9 = "PeriodIndex(['2013Q1', '2013Q2', '2013Q3'], dtype='period[Q-DEC]')"
exp10 = "PeriodIndex(['2011-01-01', '2011-02-01'], dtype='period[3D]')"
for idx, expected in zip(
[idx1, idx2, idx3, idx4, idx5, idx6, idx7, idx8, idx9, idx10],
[exp1, exp2, exp3, exp4, exp5, exp6, exp7, exp8, exp9, exp10],
):
result = getattr(idx, method)()
assert result == expected
def test_representation_to_series(self):
# GH#10971
idx1 = PeriodIndex([], freq="D")
idx2 = PeriodIndex(["2011-01-01"], freq="D")
idx3 = PeriodIndex(["2011-01-01", "2011-01-02"], freq="D")
idx4 = PeriodIndex(["2011-01-01", "2011-01-02", "2011-01-03"], freq="D")
idx5 = PeriodIndex(["2011", "2012", "2013"], freq="A")
idx6 = PeriodIndex(["2011-01-01 09:00", "2012-02-01 10:00", "NaT"], freq="H")
idx7 = pd.period_range("2013Q1", periods=1, freq="Q")
idx8 = pd.period_range("2013Q1", periods=2, freq="Q")
idx9 = pd.period_range("2013Q1", periods=3, freq="Q")
exp1 = """Series([], dtype: period[D])"""
exp2 = """0 2011-01-01
dtype: period[D]"""
exp3 = """0 2011-01-01
1 2011-01-02
dtype: period[D]"""
exp4 = """0 2011-01-01
1 2011-01-02
2 2011-01-03
dtype: period[D]"""
exp5 = """0 2011
1 2012
2 2013
dtype: period[A-DEC]"""
exp6 = """0 2011-01-01 09:00
1 2012-02-01 10:00
2 NaT
dtype: period[H]"""
exp7 = """0 2013Q1
dtype: period[Q-DEC]"""
exp8 = """0 2013Q1
1 2013Q2
dtype: period[Q-DEC]"""
exp9 = """0 2013Q1
1 2013Q2
2 2013Q3
dtype: period[Q-DEC]"""
for idx, expected in zip(
[idx1, idx2, idx3, idx4, idx5, idx6, idx7, idx8, idx9],
[exp1, exp2, exp3, exp4, exp5, exp6, exp7, exp8, exp9],
):
result = repr(Series(idx))
assert result == expected
def test_summary(self):
# GH#9116
idx1 = PeriodIndex([], freq="D")
idx2 = PeriodIndex(["2011-01-01"], freq="D")
idx3 = PeriodIndex(["2011-01-01", "2011-01-02"], freq="D")
idx4 = PeriodIndex(["2011-01-01", "2011-01-02", "2011-01-03"], freq="D")
idx5 = PeriodIndex(["2011", "2012", "2013"], freq="A")
idx6 = PeriodIndex(["2011-01-01 09:00", "2012-02-01 10:00", "NaT"], freq="H")
idx7 = pd.period_range("2013Q1", periods=1, freq="Q")
idx8 = pd.period_range("2013Q1", periods=2, freq="Q")
idx9 = pd.period_range("2013Q1", periods=3, freq="Q")
exp1 = """PeriodIndex: 0 entries
Freq: D"""
exp2 = """PeriodIndex: 1 entries, 2011-01-01 to 2011-01-01
Freq: D"""
exp3 = """PeriodIndex: 2 entries, 2011-01-01 to 2011-01-02
Freq: D"""
exp4 = """PeriodIndex: 3 entries, 2011-01-01 to 2011-01-03
Freq: D"""
exp5 = """PeriodIndex: 3 entries, 2011 to 2013
Freq: A-DEC"""
exp6 = """PeriodIndex: 3 entries, 2011-01-01 09:00 to NaT
Freq: H"""
exp7 = """PeriodIndex: 1 entries, 2013Q1 to 2013Q1
Freq: Q-DEC"""
exp8 = """PeriodIndex: 2 entries, 2013Q1 to 2013Q2
Freq: Q-DEC"""
exp9 = """PeriodIndex: 3 entries, 2013Q1 to 2013Q3
Freq: Q-DEC"""
for idx, expected in zip(
[idx1, idx2, idx3, idx4, idx5, idx6, idx7, idx8, idx9],
[exp1, exp2, exp3, exp4, exp5, exp6, exp7, exp8, exp9],
):
result = idx._summary()
assert result == expected

View File

@ -0,0 +1,21 @@
import pytest
from pandas import (
offsets,
period_range,
)
import pandas._testing as tm
class TestFreq:
def test_freq_setter_deprecated(self):
# GH#20678
idx = period_range("2018Q1", periods=4, freq="Q")
# no warning for getter
with tm.assert_produces_warning(None):
idx.freq
# warning for setter
with pytest.raises(AttributeError, match="can't set attribute"):
idx.freq = offsets.Day()

View File

@ -0,0 +1,930 @@
from datetime import (
datetime,
timedelta,
)
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
from pandas.core.api import (
Float64Index,
Int64Index,
)
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)
def test_getitem_day(self):
# GH#6716
# Confirm DatetimeIndex and PeriodIndex works identically
didx = date_range(start="2013/01/01", freq="D", periods=400)
pidx = period_range(start="2013/01/01", freq="D", periods=400)
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"], 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)
# TODO: This method came from test_period; de-dup with version above
@pytest.mark.parametrize("method", [None, "pad", "backfill", "nearest"])
@pytest.mark.filterwarnings("ignore:Passing method:FutureWarning")
def test_get_loc_method(self, method):
idx = period_range("2000-01-01", periods=3)
assert idx.get_loc(idx[1], 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
key = idx[1].asfreq("H", how="start")
with pytest.raises(KeyError, match=str(key)):
idx.get_loc(key, method=method)
# TODO: This method came from test_period; de-dup with version above
@pytest.mark.filterwarnings("ignore:Passing method:FutureWarning")
def test_get_loc3(self):
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(),
],
)
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:
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 = Series(np.array([1, 2, 3]), index=idx0)
expected0 = 2
with tm.assert_produces_warning(FutureWarning):
result0 = idx0.get_value(input0, p1)
assert result0 == expected0
idx1 = PeriodIndex([p1, p1, p2])
input1 = Series(np.array([1, 2, 3]), index=idx1)
expected1 = input1.iloc[[0, 1]]
with tm.assert_produces_warning(FutureWarning):
result1 = idx1.get_value(input1, p1)
tm.assert_series_equal(result1, expected1)
idx2 = PeriodIndex([p1, p2, p1])
input2 = Series(np.array([1, 2, 3]), index=idx2)
expected2 = input2.iloc[[0, 2]]
with tm.assert_produces_warning(FutureWarning):
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 = Series(range(7, 10), index=pi)
ts = dti[0]
assert pi.get_loc(ts) == 0
with tm.assert_produces_warning(FutureWarning):
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"):
with tm.assert_produces_warning(FutureWarning):
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
with tm.assert_produces_warning(FutureWarning):
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 = Series(range(3), index=pi)
with pytest.raises(IndexError, match=msg):
with tm.assert_produces_warning(FutureWarning):
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 = Series(range(3), index=pi2)
with pytest.raises(IndexError, match=msg):
with tm.assert_produces_warning(FutureWarning):
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 = 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):
with tm.assert_produces_warning(FutureWarning):
idx0.get_value(ser, 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 not Period("2007-01", freq="D") in rng
assert not Period("2007-01", freq="2M") 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(Int64Index(pi.asi8), mask)
with pytest.raises(TypeError, match=msg):
pi.asof_locs(Float64Index(pi.asi8), 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)

View File

@ -0,0 +1,58 @@
import numpy as np
import pytest
from pandas._libs.tslibs import IncompatibleFrequency
from pandas import (
Index,
PeriodIndex,
period_range,
)
import pandas._testing as tm
class TestJoin:
def test_join_outer_indexer(self):
pi = period_range("1/1/2000", "1/20/2000", freq="D")
result = pi._outer_indexer(pi)
tm.assert_extension_array_equal(result[0], pi._values)
tm.assert_numpy_array_equal(result[1], np.arange(len(pi), dtype=np.intp))
tm.assert_numpy_array_equal(result[2], np.arange(len(pi), dtype=np.intp))
def test_joins(self, join_type):
index = period_range("1/1/2000", "1/20/2000", freq="D")
joined = index.join(index[:-5], how=join_type)
assert isinstance(joined, PeriodIndex)
assert joined.freq == index.freq
def test_join_self(self, join_type):
index = period_range("1/1/2000", "1/20/2000", freq="D")
res = index.join(index, how=join_type)
assert index is res
def test_join_does_not_recur(self):
df = tm.makeCustomDataframe(
3,
2,
data_gen_f=lambda *args: np.random.randint(2),
c_idx_type="p",
r_idx_type="dt",
)
ser = df.iloc[:2, 0]
res = ser.index.join(df.columns, how="outer")
expected = Index(
[ser.index[0], ser.index[1], df.columns[0], df.columns[1]], object
)
tm.assert_index_equal(res, expected)
def test_join_mismatched_freq_raises(self):
index = period_range("1/1/2000", "1/20/2000", freq="D")
index3 = period_range("1/1/2000", "1/20/2000", freq="2D")
msg = r".*Input has different freq=2D from Period\(freq=D\)"
with pytest.raises(IncompatibleFrequency, match=msg):
index.join(index3)

View File

@ -0,0 +1,42 @@
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

View File

@ -0,0 +1,201 @@
import numpy as np
import pytest
from pandas import (
DataFrame,
PeriodIndex,
Series,
date_range,
period_range,
)
import pandas._testing as tm
class TestPeriodIndex:
def test_getitem_periodindex_duplicates_string_slice(self):
# monotonic
idx = PeriodIndex([2000, 2007, 2007, 2009, 2009], freq="A-JUN")
ts = Series(np.random.randn(len(idx)), index=idx)
result = ts["2007"]
expected = ts[1:3]
tm.assert_series_equal(result, expected)
result[:] = 1
assert (ts[1:3] == 1).all()
# not monotonic
idx = PeriodIndex([2000, 2007, 2007, 2009, 2007], freq="A-JUN")
ts = Series(np.random.randn(len(idx)), index=idx)
result = ts["2007"]
expected = ts[idx == "2007"]
tm.assert_series_equal(result, expected)
def test_getitem_periodindex_quarter_string(self):
pi = PeriodIndex(["2Q05", "3Q05", "4Q05", "1Q06", "2Q06"], freq="Q")
ser = Series(np.random.rand(len(pi)), index=pi).cumsum()
# Todo: fix these accessors!
assert ser["05Q4"] == ser[2]
def test_pindex_slice_index(self):
pi = period_range(start="1/1/10", end="12/31/12", freq="M")
s = Series(np.random.rand(len(pi)), index=pi)
res = s["2010"]
exp = s[0:12]
tm.assert_series_equal(res, exp)
res = s["2011"]
exp = s[12:24]
tm.assert_series_equal(res, exp)
@pytest.mark.parametrize("make_range", [date_range, period_range])
def test_range_slice_day(self, make_range):
# GH#6716
idx = make_range(start="2013/01/01", freq="D", periods=400)
msg = "slice indices must be integers or None or have an __index__ method"
# slices against index should raise IndexError
values = [
"2014",
"2013/02",
"2013/01/02",
"2013/02/01 9H",
"2013/02/01 09:00",
]
for v in values:
with pytest.raises(TypeError, match=msg):
idx[v:]
s = Series(np.random.rand(len(idx)), index=idx)
tm.assert_series_equal(s["2013/01/02":], s[1:])
tm.assert_series_equal(s["2013/01/02":"2013/01/05"], s[1:5])
tm.assert_series_equal(s["2013/02":], s[31:])
tm.assert_series_equal(s["2014":], s[365:])
invalid = ["2013/02/01 9H", "2013/02/01 09:00"]
for v in invalid:
with pytest.raises(TypeError, match=msg):
idx[v:]
@pytest.mark.parametrize("make_range", [date_range, period_range])
def test_range_slice_seconds(self, make_range):
# GH#6716
idx = make_range(start="2013/01/01 09:00:00", freq="S", periods=4000)
msg = "slice indices must be integers or None or have an __index__ method"
# slices against index should raise IndexError
values = [
"2014",
"2013/02",
"2013/01/02",
"2013/02/01 9H",
"2013/02/01 09:00",
]
for v in values:
with pytest.raises(TypeError, match=msg):
idx[v:]
s = Series(np.random.rand(len(idx)), index=idx)
tm.assert_series_equal(s["2013/01/01 09:05":"2013/01/01 09:10"], s[300:660])
tm.assert_series_equal(s["2013/01/01 10:00":"2013/01/01 10:05"], s[3600:3960])
tm.assert_series_equal(s["2013/01/01 10H":], s[3600:])
tm.assert_series_equal(s[:"2013/01/01 09:30"], s[:1860])
for d in ["2013/01/01", "2013/01", "2013"]:
tm.assert_series_equal(s[d:], s)
@pytest.mark.parametrize("make_range", [date_range, period_range])
def test_range_slice_outofbounds(self, make_range):
# GH#5407
idx = make_range(start="2013/10/01", freq="D", periods=10)
df = DataFrame({"units": [100 + i for i in range(10)]}, index=idx)
empty = DataFrame(index=type(idx)([], freq="D"), columns=["units"])
empty["units"] = empty["units"].astype("int64")
tm.assert_frame_equal(df["2013/09/01":"2013/09/30"], empty)
tm.assert_frame_equal(df["2013/09/30":"2013/10/02"], df.iloc[:2])
tm.assert_frame_equal(df["2013/10/01":"2013/10/02"], df.iloc[:2])
tm.assert_frame_equal(df["2013/10/02":"2013/09/30"], empty)
tm.assert_frame_equal(df["2013/10/15":"2013/10/17"], empty)
tm.assert_frame_equal(df["2013-06":"2013-09"], empty)
tm.assert_frame_equal(df["2013-11":"2013-12"], empty)
@pytest.mark.parametrize("make_range", [date_range, period_range])
def test_maybe_cast_slice_bound(self, make_range, frame_or_series):
idx = make_range(start="2013/10/01", freq="D", periods=10)
obj = DataFrame({"units": [100 + i for i in range(10)]}, index=idx)
obj = tm.get_obj(obj, frame_or_series)
msg = (
f"cannot do slice indexing on {type(idx).__name__} with "
r"these indexers \[foo\] of type str"
)
# Check the lower-level calls are raising where expected.
with pytest.raises(TypeError, match=msg):
idx._maybe_cast_slice_bound("foo", "left")
with pytest.raises(TypeError, match=msg):
idx.get_slice_bound("foo", "left")
with pytest.raises(TypeError, match=msg):
obj["2013/09/30":"foo"]
with pytest.raises(TypeError, match=msg):
obj["foo":"2013/09/30"]
with pytest.raises(TypeError, match=msg):
obj.loc["2013/09/30":"foo"]
with pytest.raises(TypeError, match=msg):
obj.loc["foo":"2013/09/30"]
def test_partial_slice_doesnt_require_monotonicity(self):
# See also: DatetimeIndex test ofm the same name
dti = date_range("2014-01-01", periods=30, freq="30D")
pi = dti.to_period("D")
ser_montonic = Series(np.arange(30), index=pi)
shuffler = list(range(0, 30, 2)) + list(range(1, 31, 2))
ser = ser_montonic[shuffler]
nidx = ser.index
# Manually identified locations of year==2014
indexer_2014 = np.array(
[0, 1, 2, 3, 4, 5, 6, 15, 16, 17, 18, 19, 20], dtype=np.intp
)
assert (nidx[indexer_2014].year == 2014).all()
assert not (nidx[~indexer_2014].year == 2014).any()
result = nidx.get_loc("2014")
tm.assert_numpy_array_equal(result, indexer_2014)
expected = ser[indexer_2014]
with tm.assert_produces_warning(FutureWarning):
result = nidx.get_value(ser, "2014")
tm.assert_series_equal(result, expected)
result = ser.loc["2014"]
tm.assert_series_equal(result, expected)
result = ser["2014"]
tm.assert_series_equal(result, expected)
# Manually identified locations where ser.index is within Mat 2015
indexer_may2015 = np.array([23], dtype=np.intp)
assert nidx[23].year == 2015 and nidx[23].month == 5
result = nidx.get_loc("May 2015")
tm.assert_numpy_array_equal(result, indexer_may2015)
expected = ser[indexer_may2015]
with tm.assert_produces_warning(FutureWarning):
result = nidx.get_value(ser, "May 2015")
tm.assert_series_equal(result, expected)
result = ser.loc["May 2015"]
tm.assert_series_equal(result, expected)
result = ser["May 2015"]
tm.assert_series_equal(result, expected)

View File

@ -0,0 +1,353 @@
import numpy as np
import pytest
from pandas._libs.tslibs.period import IncompatibleFrequency
from pandas import (
Index,
NaT,
Period,
PeriodIndex,
Series,
date_range,
offsets,
period_range,
)
import pandas._testing as tm
from pandas.tests.indexes.datetimelike import DatetimeLike
class TestPeriodIndex(DatetimeLike):
_index_cls = PeriodIndex
@pytest.fixture
def simple_index(self) -> Index:
return period_range("20130101", periods=5, freq="D")
@pytest.fixture(
params=[
tm.makePeriodIndex(10),
period_range("20130101", periods=10, freq="D")[::-1],
],
ids=["index_inc", "index_dec"],
)
def index(self, request):
return request.param
def test_where(self):
# This is handled in test_indexing
pass
def test_make_time_series(self):
index = period_range(freq="A", start="1/1/2001", end="12/1/2009")
series = Series(1, index=index)
assert isinstance(series, Series)
def test_view_asi8(self):
idx = PeriodIndex([], freq="M")
exp = np.array([], dtype=np.int64)
tm.assert_numpy_array_equal(idx.view("i8"), exp)
tm.assert_numpy_array_equal(idx.asi8, exp)
idx = PeriodIndex(["2011-01", NaT], freq="M")
exp = np.array([492, -9223372036854775808], dtype=np.int64)
tm.assert_numpy_array_equal(idx.view("i8"), exp)
tm.assert_numpy_array_equal(idx.asi8, exp)
exp = np.array([14975, -9223372036854775808], dtype=np.int64)
idx = PeriodIndex(["2011-01-01", NaT], freq="D")
tm.assert_numpy_array_equal(idx.view("i8"), exp)
tm.assert_numpy_array_equal(idx.asi8, exp)
def test_values(self):
idx = PeriodIndex([], freq="M")
exp = np.array([], dtype=object)
tm.assert_numpy_array_equal(idx.values, exp)
tm.assert_numpy_array_equal(idx.to_numpy(), exp)
exp = np.array([], dtype=np.int64)
tm.assert_numpy_array_equal(idx.asi8, exp)
idx = PeriodIndex(["2011-01", NaT], freq="M")
exp = np.array([Period("2011-01", freq="M"), NaT], dtype=object)
tm.assert_numpy_array_equal(idx.values, exp)
tm.assert_numpy_array_equal(idx.to_numpy(), exp)
exp = np.array([492, -9223372036854775808], dtype=np.int64)
tm.assert_numpy_array_equal(idx.asi8, exp)
idx = PeriodIndex(["2011-01-01", NaT], freq="D")
exp = np.array([Period("2011-01-01", freq="D"), NaT], dtype=object)
tm.assert_numpy_array_equal(idx.values, exp)
tm.assert_numpy_array_equal(idx.to_numpy(), exp)
exp = np.array([14975, -9223372036854775808], dtype=np.int64)
tm.assert_numpy_array_equal(idx.asi8, exp)
def test_period_index_length(self):
pi = period_range(freq="A", start="1/1/2001", end="12/1/2009")
assert len(pi) == 9
pi = period_range(freq="Q", start="1/1/2001", end="12/1/2009")
assert len(pi) == 4 * 9
pi = period_range(freq="M", start="1/1/2001", end="12/1/2009")
assert len(pi) == 12 * 9
start = Period("02-Apr-2005", "B")
i1 = period_range(start=start, periods=20)
assert len(i1) == 20
assert i1.freq == start.freq
assert i1[0] == start
end_intv = Period("2006-12-31", "W")
i1 = period_range(end=end_intv, periods=10)
assert len(i1) == 10
assert i1.freq == end_intv.freq
assert i1[-1] == end_intv
end_intv = Period("2006-12-31", "1w")
i2 = period_range(end=end_intv, periods=10)
assert len(i1) == len(i2)
assert (i1 == i2).all()
assert i1.freq == i2.freq
msg = "start and end must have same freq"
with pytest.raises(ValueError, match=msg):
period_range(start=start, end=end_intv)
end_intv = Period("2005-05-01", "B")
i1 = period_range(start=start, end=end_intv)
msg = (
"Of the three parameters: start, end, and periods, exactly two "
"must be specified"
)
with pytest.raises(ValueError, match=msg):
period_range(start=start)
# infer freq from first element
i2 = PeriodIndex([end_intv, Period("2005-05-05", "B")])
assert len(i2) == 2
assert i2[0] == end_intv
i2 = PeriodIndex(np.array([end_intv, Period("2005-05-05", "B")]))
assert len(i2) == 2
assert i2[0] == end_intv
# Mixed freq should fail
vals = [end_intv, Period("2006-12-31", "w")]
msg = r"Input has different freq=W-SUN from PeriodIndex\(freq=B\)"
with pytest.raises(IncompatibleFrequency, match=msg):
PeriodIndex(vals)
vals = np.array(vals)
with pytest.raises(ValueError, match=msg):
PeriodIndex(vals)
def test_fields(self):
# year, month, day, hour, minute
# second, weekofyear, week, dayofweek, weekday, dayofyear, quarter
# qyear
pi = period_range(freq="A", start="1/1/2001", end="12/1/2005")
self._check_all_fields(pi)
pi = period_range(freq="Q", start="1/1/2001", end="12/1/2002")
self._check_all_fields(pi)
pi = period_range(freq="M", start="1/1/2001", end="1/1/2002")
self._check_all_fields(pi)
pi = period_range(freq="D", start="12/1/2001", end="6/1/2001")
self._check_all_fields(pi)
pi = period_range(freq="B", start="12/1/2001", end="6/1/2001")
self._check_all_fields(pi)
pi = period_range(freq="H", start="12/31/2001", end="1/1/2002 23:00")
self._check_all_fields(pi)
pi = period_range(freq="Min", start="12/31/2001", end="1/1/2002 00:20")
self._check_all_fields(pi)
pi = period_range(
freq="S", start="12/31/2001 00:00:00", end="12/31/2001 00:05:00"
)
self._check_all_fields(pi)
end_intv = Period("2006-12-31", "W")
i1 = period_range(end=end_intv, periods=10)
self._check_all_fields(i1)
def _check_all_fields(self, periodindex):
fields = [
"year",
"month",
"day",
"hour",
"minute",
"second",
"weekofyear",
"week",
"dayofweek",
"day_of_week",
"dayofyear",
"day_of_year",
"quarter",
"qyear",
"days_in_month",
]
periods = list(periodindex)
ser = Series(periodindex)
for field in fields:
field_idx = getattr(periodindex, field)
assert len(periodindex) == len(field_idx)
for x, val in zip(periods, field_idx):
assert getattr(x, field) == val
if len(ser) == 0:
continue
field_s = getattr(ser.dt, field)
assert len(periodindex) == len(field_s)
for x, val in zip(periods, field_s):
assert getattr(x, field) == val
def test_is_(self):
create_index = lambda: period_range(freq="A", start="1/1/2001", end="12/1/2009")
index = create_index()
assert index.is_(index)
assert not index.is_(create_index())
assert index.is_(index.view())
assert index.is_(index.view().view().view().view().view())
assert index.view().is_(index)
ind2 = index.view()
index.name = "Apple"
assert ind2.is_(index)
assert not index.is_(index[:])
assert not index.is_(index.asfreq("M"))
assert not index.is_(index.asfreq("A"))
assert not index.is_(index - 2)
assert not index.is_(index - 0)
def test_index_unique(self):
idx = PeriodIndex([2000, 2007, 2007, 2009, 2009], freq="A-JUN")
expected = PeriodIndex([2000, 2007, 2009], freq="A-JUN")
tm.assert_index_equal(idx.unique(), expected)
assert idx.nunique() == 3
def test_shift(self):
# This is tested in test_arithmetic
pass
def test_negative_ordinals(self):
Period(ordinal=-1000, freq="A")
Period(ordinal=0, freq="A")
idx1 = PeriodIndex(ordinal=[-1, 0, 1], freq="A")
idx2 = PeriodIndex(ordinal=np.array([-1, 0, 1]), freq="A")
tm.assert_index_equal(idx1, idx2)
def test_pindex_fieldaccessor_nat(self):
idx = PeriodIndex(
["2011-01", "2011-02", "NaT", "2012-03", "2012-04"], freq="D", name="name"
)
exp = Index([2011, 2011, -1, 2012, 2012], dtype=np.int64, name="name")
tm.assert_index_equal(idx.year, exp)
exp = Index([1, 2, -1, 3, 4], dtype=np.int64, name="name")
tm.assert_index_equal(idx.month, exp)
def test_pindex_multiples(self):
expected = PeriodIndex(
["2011-01", "2011-03", "2011-05", "2011-07", "2011-09", "2011-11"],
freq="2M",
)
pi = period_range(start="1/1/11", end="12/31/11", freq="2M")
tm.assert_index_equal(pi, expected)
assert pi.freq == offsets.MonthEnd(2)
assert pi.freqstr == "2M"
pi = period_range(start="1/1/11", periods=6, freq="2M")
tm.assert_index_equal(pi, expected)
assert pi.freq == offsets.MonthEnd(2)
assert pi.freqstr == "2M"
def test_iteration(self):
index = period_range(start="1/1/10", periods=4, freq="B")
result = list(index)
assert isinstance(result[0], Period)
assert result[0].freq == index.freq
def test_with_multi_index(self):
# #1705
index = date_range("1/1/2012", periods=4, freq="12H")
index_as_arrays = [index.to_period(freq="D"), index.hour]
s = Series([0, 1, 2, 3], index_as_arrays)
assert isinstance(s.index.levels[0], PeriodIndex)
assert isinstance(s.index.values[0][0], Period)
def test_map(self):
# test_map_dictlike generally tests
index = PeriodIndex([2005, 2007, 2009], freq="A")
result = index.map(lambda x: x.ordinal)
exp = Index([x.ordinal for x in index])
tm.assert_index_equal(result, exp)
def test_format_empty(self):
# GH35712
empty_idx = self._index_cls([], freq="A")
assert empty_idx.format() == []
assert empty_idx.format(name=True) == [""]
def test_maybe_convert_timedelta():
pi = PeriodIndex(["2000", "2001"], freq="D")
offset = offsets.Day(2)
assert pi._maybe_convert_timedelta(offset) == 2
assert pi._maybe_convert_timedelta(2) == 2
offset = offsets.BusinessDay()
msg = r"Input has different freq=B from PeriodIndex\(freq=D\)"
with pytest.raises(ValueError, match=msg):
pi._maybe_convert_timedelta(offset)
@pytest.mark.parametrize("array", [True, False])
def test_dunder_array(array):
obj = PeriodIndex(["2000-01-01", "2001-01-01"], freq="D")
if array:
obj = obj._data
expected = np.array([obj[0], obj[1]], dtype=object)
result = np.array(obj)
tm.assert_numpy_array_equal(result, expected)
result = np.asarray(obj)
tm.assert_numpy_array_equal(result, expected)
expected = obj.asi8
for dtype in ["i8", "int64", np.int64]:
result = np.array(obj, dtype=dtype)
tm.assert_numpy_array_equal(result, expected)
result = np.asarray(obj, dtype=dtype)
tm.assert_numpy_array_equal(result, expected)
for dtype in ["float64", "int32", "uint64"]:
msg = "argument must be"
with pytest.raises(TypeError, match=msg):
np.array(obj, dtype=dtype)
with pytest.raises(TypeError, match=msg):
np.array(obj, dtype=getattr(np, dtype))

View File

@ -0,0 +1,121 @@
import numpy as np
import pytest
from pandas import (
NaT,
Period,
PeriodIndex,
date_range,
period_range,
)
import pandas._testing as tm
class TestPeriodRange:
def test_required_arguments(self):
msg = (
"Of the three parameters: start, end, and periods, exactly two "
"must be specified"
)
with pytest.raises(ValueError, match=msg):
period_range("2011-1-1", "2012-1-1", "B")
@pytest.mark.parametrize("freq", ["D", "W", "M", "Q", "A"])
def test_construction_from_string(self, freq):
# non-empty
expected = date_range(
start="2017-01-01", periods=5, freq=freq, name="foo"
).to_period()
start, end = str(expected[0]), str(expected[-1])
result = period_range(start=start, end=end, freq=freq, name="foo")
tm.assert_index_equal(result, expected)
result = period_range(start=start, periods=5, freq=freq, name="foo")
tm.assert_index_equal(result, expected)
result = period_range(end=end, periods=5, freq=freq, name="foo")
tm.assert_index_equal(result, expected)
# empty
expected = PeriodIndex([], freq=freq, name="foo")
result = period_range(start=start, periods=0, freq=freq, name="foo")
tm.assert_index_equal(result, expected)
result = period_range(end=end, periods=0, freq=freq, name="foo")
tm.assert_index_equal(result, expected)
result = period_range(start=end, end=start, freq=freq, name="foo")
tm.assert_index_equal(result, expected)
def test_construction_from_period(self):
# upsampling
start, end = Period("2017Q1", freq="Q"), Period("2018Q1", freq="Q")
expected = date_range(
start="2017-03-31", end="2018-03-31", freq="M", name="foo"
).to_period()
result = period_range(start=start, end=end, freq="M", name="foo")
tm.assert_index_equal(result, expected)
# downsampling
start, end = Period("2017-1", freq="M"), Period("2019-12", freq="M")
expected = date_range(
start="2017-01-31", end="2019-12-31", freq="Q", name="foo"
).to_period()
result = period_range(start=start, end=end, freq="Q", name="foo")
tm.assert_index_equal(result, expected)
# test for issue # 21793
start, end = Period("2017Q1", freq="Q"), Period("2018Q1", freq="Q")
idx = period_range(start=start, end=end, freq="Q", name="foo")
result = idx == idx.values
expected = np.array([True, True, True, True, True])
tm.assert_numpy_array_equal(result, expected)
# empty
expected = PeriodIndex([], freq="W", name="foo")
result = period_range(start=start, periods=0, freq="W", name="foo")
tm.assert_index_equal(result, expected)
result = period_range(end=end, periods=0, freq="W", name="foo")
tm.assert_index_equal(result, expected)
result = period_range(start=end, end=start, freq="W", name="foo")
tm.assert_index_equal(result, expected)
def test_errors(self):
# not enough params
msg = (
"Of the three parameters: start, end, and periods, "
"exactly two must be specified"
)
with pytest.raises(ValueError, match=msg):
period_range(start="2017Q1")
with pytest.raises(ValueError, match=msg):
period_range(end="2017Q1")
with pytest.raises(ValueError, match=msg):
period_range(periods=5)
with pytest.raises(ValueError, match=msg):
period_range()
# too many params
with pytest.raises(ValueError, match=msg):
period_range(start="2017Q1", end="2018Q1", periods=8, freq="Q")
# start/end NaT
msg = "start and end must not be NaT"
with pytest.raises(ValueError, match=msg):
period_range(start=NaT, end="2018Q1")
with pytest.raises(ValueError, match=msg):
period_range(start="2017Q1", end=NaT)
# invalid periods param
msg = "periods must be a number, got foo"
with pytest.raises(TypeError, match=msg):
period_range(start="2017Q1", periods="foo")

View File

@ -0,0 +1,26 @@
import numpy as np
import pytest
from pandas import (
NaT,
PeriodIndex,
period_range,
)
import pandas._testing as tm
from pandas.tseries import offsets
class TestPickle:
@pytest.mark.parametrize("freq", ["D", "M", "A"])
def test_pickle_round_trip(self, freq):
idx = PeriodIndex(["2016-05-16", "NaT", NaT, np.NaN], freq=freq)
result = tm.round_trip_pickle(idx)
tm.assert_index_equal(result, idx)
def test_pickle_freq(self):
# GH#2891
prng = period_range("1/1/2011", "1/1/2012", freq="M")
new_prng = tm.round_trip_pickle(prng)
assert new_prng.freq == offsets.MonthEnd()
assert new_prng.freqstr == "M"

View File

@ -0,0 +1,23 @@
import pytest
import pandas as pd
class TestResolution:
@pytest.mark.parametrize(
"freq,expected",
[
("A", "year"),
("Q", "quarter"),
("M", "month"),
("D", "day"),
("H", "hour"),
("T", "minute"),
("S", "second"),
("L", "millisecond"),
("U", "microsecond"),
],
)
def test_resolution(self, freq, expected):
idx = pd.period_range(start="2013-04-01", periods=30, freq=freq)
assert idx.resolution == expected

View File

@ -0,0 +1,32 @@
"""Tests for PeriodIndex behaving like a vectorized Period scalar"""
from pandas import (
Timedelta,
date_range,
period_range,
)
import pandas._testing as tm
class TestPeriodIndexOps:
def test_start_time(self):
# GH#17157
index = period_range(freq="M", start="2016-01-01", end="2016-05-31")
expected_index = date_range("2016-01-01", end="2016-05-31", freq="MS")
tm.assert_index_equal(index.start_time, expected_index)
def test_end_time(self):
# GH#17157
index = period_range(freq="M", start="2016-01-01", end="2016-05-31")
expected_index = date_range("2016-01-01", end="2016-05-31", freq="M")
expected_index += Timedelta(1, "D") - Timedelta(1, "ns")
tm.assert_index_equal(index.end_time, expected_index)
def test_end_time_business_friday(self):
# GH#34449
pi = period_range("1990-01-05", freq="B", periods=1)
result = pi.end_time
dti = date_range("1990-01-05", freq="D", periods=1)._with_freq(None)
expected = dti + Timedelta(days=1, nanoseconds=-1)
tm.assert_index_equal(result, expected)

View File

@ -0,0 +1,80 @@
import numpy as np
import pytest
from pandas._libs.tslibs import IncompatibleFrequency
from pandas import (
NaT,
Period,
PeriodIndex,
)
import pandas._testing as tm
class TestSearchsorted:
@pytest.mark.parametrize("freq", ["D", "2D"])
def test_searchsorted(self, freq):
pidx = PeriodIndex(
["2014-01-01", "2014-01-02", "2014-01-03", "2014-01-04", "2014-01-05"],
freq=freq,
)
p1 = Period("2014-01-01", freq=freq)
assert pidx.searchsorted(p1) == 0
p2 = Period("2014-01-04", freq=freq)
assert pidx.searchsorted(p2) == 3
assert pidx.searchsorted(NaT) == 5
msg = "Input has different freq=H from PeriodArray"
with pytest.raises(IncompatibleFrequency, match=msg):
pidx.searchsorted(Period("2014-01-01", freq="H"))
msg = "Input has different freq=5D from PeriodArray"
with pytest.raises(IncompatibleFrequency, match=msg):
pidx.searchsorted(Period("2014-01-01", freq="5D"))
def test_searchsorted_different_argument_classes(self, listlike_box):
pidx = PeriodIndex(
["2014-01-01", "2014-01-02", "2014-01-03", "2014-01-04", "2014-01-05"],
freq="D",
)
result = pidx.searchsorted(listlike_box(pidx))
expected = np.arange(len(pidx), dtype=result.dtype)
tm.assert_numpy_array_equal(result, expected)
result = pidx._data.searchsorted(listlike_box(pidx))
tm.assert_numpy_array_equal(result, expected)
def test_searchsorted_invalid(self):
pidx = PeriodIndex(
["2014-01-01", "2014-01-02", "2014-01-03", "2014-01-04", "2014-01-05"],
freq="D",
)
other = np.array([0, 1], dtype=np.int64)
msg = "|".join(
[
"searchsorted requires compatible dtype or scalar",
"value should be a 'Period', 'NaT', or array of those. Got",
]
)
with pytest.raises(TypeError, match=msg):
pidx.searchsorted(other)
with pytest.raises(TypeError, match=msg):
pidx.searchsorted(other.astype("timedelta64[ns]"))
with pytest.raises(TypeError, match=msg):
pidx.searchsorted(np.timedelta64(4))
with pytest.raises(TypeError, match=msg):
pidx.searchsorted(np.timedelta64("NaT", "ms"))
with pytest.raises(TypeError, match=msg):
pidx.searchsorted(np.datetime64(4, "ns"))
with pytest.raises(TypeError, match=msg):
pidx.searchsorted(np.datetime64("NaT", "ns"))

View File

@ -0,0 +1,360 @@
import numpy as np
import pandas as pd
from pandas import (
PeriodIndex,
date_range,
period_range,
)
import pandas._testing as tm
def _permute(obj):
return obj.take(np.random.permutation(len(obj)))
class TestPeriodIndex:
def test_union(self, sort):
# union
other1 = period_range("1/1/2000", freq="D", periods=5)
rng1 = period_range("1/6/2000", freq="D", periods=5)
expected1 = PeriodIndex(
[
"2000-01-06",
"2000-01-07",
"2000-01-08",
"2000-01-09",
"2000-01-10",
"2000-01-01",
"2000-01-02",
"2000-01-03",
"2000-01-04",
"2000-01-05",
],
freq="D",
)
rng2 = period_range("1/1/2000", freq="D", periods=5)
other2 = period_range("1/4/2000", freq="D", periods=5)
expected2 = period_range("1/1/2000", freq="D", periods=8)
rng3 = period_range("1/1/2000", freq="D", periods=5)
other3 = PeriodIndex([], freq="D")
expected3 = period_range("1/1/2000", freq="D", periods=5)
rng4 = period_range("2000-01-01 09:00", freq="H", periods=5)
other4 = period_range("2000-01-02 09:00", freq="H", periods=5)
expected4 = PeriodIndex(
[
"2000-01-01 09:00",
"2000-01-01 10:00",
"2000-01-01 11:00",
"2000-01-01 12:00",
"2000-01-01 13:00",
"2000-01-02 09:00",
"2000-01-02 10:00",
"2000-01-02 11:00",
"2000-01-02 12:00",
"2000-01-02 13:00",
],
freq="H",
)
rng5 = PeriodIndex(
["2000-01-01 09:01", "2000-01-01 09:03", "2000-01-01 09:05"], freq="T"
)
other5 = PeriodIndex(
["2000-01-01 09:01", "2000-01-01 09:05", "2000-01-01 09:08"], freq="T"
)
expected5 = PeriodIndex(
[
"2000-01-01 09:01",
"2000-01-01 09:03",
"2000-01-01 09:05",
"2000-01-01 09:08",
],
freq="T",
)
rng6 = period_range("2000-01-01", freq="M", periods=7)
other6 = period_range("2000-04-01", freq="M", periods=7)
expected6 = period_range("2000-01-01", freq="M", periods=10)
rng7 = period_range("2003-01-01", freq="A", periods=5)
other7 = period_range("1998-01-01", freq="A", periods=8)
expected7 = PeriodIndex(
[
"2003",
"2004",
"2005",
"2006",
"2007",
"1998",
"1999",
"2000",
"2001",
"2002",
],
freq="A",
)
rng8 = PeriodIndex(
["1/3/2000", "1/2/2000", "1/1/2000", "1/5/2000", "1/4/2000"], freq="D"
)
other8 = period_range("1/6/2000", freq="D", periods=5)
expected8 = PeriodIndex(
[
"1/3/2000",
"1/2/2000",
"1/1/2000",
"1/5/2000",
"1/4/2000",
"1/6/2000",
"1/7/2000",
"1/8/2000",
"1/9/2000",
"1/10/2000",
],
freq="D",
)
for rng, other, expected in [
(rng1, other1, expected1),
(rng2, other2, expected2),
(rng3, other3, expected3),
(rng4, other4, expected4),
(rng5, other5, expected5),
(rng6, other6, expected6),
(rng7, other7, expected7),
(rng8, other8, expected8),
]:
result_union = rng.union(other, sort=sort)
if sort is None:
expected = expected.sort_values()
tm.assert_index_equal(result_union, expected)
def test_union_misc(self, sort):
index = period_range("1/1/2000", "1/20/2000", freq="D")
result = index[:-5].union(index[10:], sort=sort)
tm.assert_index_equal(result, index)
# not in order
result = _permute(index[:-5]).union(_permute(index[10:]), sort=sort)
if sort is None:
tm.assert_index_equal(result, index)
assert tm.equalContents(result, index)
# cast if different frequencies
index = period_range("1/1/2000", "1/20/2000", freq="D")
index2 = period_range("1/1/2000", "1/20/2000", freq="W-WED")
result = index.union(index2, sort=sort)
expected = index.astype(object).union(index2.astype(object), sort=sort)
tm.assert_index_equal(result, expected)
def test_intersection(self, sort):
index = period_range("1/1/2000", "1/20/2000", freq="D")
result = index[:-5].intersection(index[10:], sort=sort)
tm.assert_index_equal(result, index[10:-5])
# not in order
left = _permute(index[:-5])
right = _permute(index[10:])
result = left.intersection(right, sort=sort)
if sort is None:
tm.assert_index_equal(result, index[10:-5])
assert tm.equalContents(result, index[10:-5])
# cast if different frequencies
index = period_range("1/1/2000", "1/20/2000", freq="D")
index2 = period_range("1/1/2000", "1/20/2000", freq="W-WED")
result = index.intersection(index2, sort=sort)
expected = pd.Index([], dtype=object)
tm.assert_index_equal(result, expected)
index3 = period_range("1/1/2000", "1/20/2000", freq="2D")
result = index.intersection(index3, sort=sort)
tm.assert_index_equal(result, expected)
def test_intersection_cases(self, sort):
base = period_range("6/1/2000", "6/30/2000", freq="D", name="idx")
# if target has the same name, it is preserved
rng2 = period_range("5/15/2000", "6/20/2000", freq="D", name="idx")
expected2 = period_range("6/1/2000", "6/20/2000", freq="D", name="idx")
# if target name is different, it will be reset
rng3 = period_range("5/15/2000", "6/20/2000", freq="D", name="other")
expected3 = period_range("6/1/2000", "6/20/2000", freq="D", name=None)
rng4 = period_range("7/1/2000", "7/31/2000", freq="D", name="idx")
expected4 = PeriodIndex([], name="idx", freq="D")
for (rng, expected) in [
(rng2, expected2),
(rng3, expected3),
(rng4, expected4),
]:
result = base.intersection(rng, sort=sort)
tm.assert_index_equal(result, expected)
assert result.name == expected.name
assert result.freq == expected.freq
# non-monotonic
base = PeriodIndex(
["2011-01-05", "2011-01-04", "2011-01-02", "2011-01-03"],
freq="D",
name="idx",
)
rng2 = PeriodIndex(
["2011-01-04", "2011-01-02", "2011-02-02", "2011-02-03"],
freq="D",
name="idx",
)
expected2 = PeriodIndex(["2011-01-04", "2011-01-02"], freq="D", name="idx")
rng3 = PeriodIndex(
["2011-01-04", "2011-01-02", "2011-02-02", "2011-02-03"],
freq="D",
name="other",
)
expected3 = PeriodIndex(["2011-01-04", "2011-01-02"], freq="D", name=None)
rng4 = period_range("7/1/2000", "7/31/2000", freq="D", name="idx")
expected4 = PeriodIndex([], freq="D", name="idx")
for (rng, expected) in [
(rng2, expected2),
(rng3, expected3),
(rng4, expected4),
]:
result = base.intersection(rng, sort=sort)
if sort is None:
expected = expected.sort_values()
tm.assert_index_equal(result, expected)
assert result.name == expected.name
assert result.freq == "D"
# empty same freq
rng = date_range("6/1/2000", "6/15/2000", freq="T")
result = rng[0:0].intersection(rng)
assert len(result) == 0
result = rng.intersection(rng[0:0])
assert len(result) == 0
def test_difference(self, sort):
# diff
period_rng = ["1/3/2000", "1/2/2000", "1/1/2000", "1/5/2000", "1/4/2000"]
rng1 = PeriodIndex(period_rng, freq="D")
other1 = period_range("1/6/2000", freq="D", periods=5)
expected1 = rng1
rng2 = PeriodIndex(period_rng, freq="D")
other2 = period_range("1/4/2000", freq="D", periods=5)
expected2 = PeriodIndex(["1/3/2000", "1/2/2000", "1/1/2000"], freq="D")
rng3 = PeriodIndex(period_rng, freq="D")
other3 = PeriodIndex([], freq="D")
expected3 = rng3
period_rng = [
"2000-01-01 10:00",
"2000-01-01 09:00",
"2000-01-01 12:00",
"2000-01-01 11:00",
"2000-01-01 13:00",
]
rng4 = PeriodIndex(period_rng, freq="H")
other4 = period_range("2000-01-02 09:00", freq="H", periods=5)
expected4 = rng4
rng5 = PeriodIndex(
["2000-01-01 09:03", "2000-01-01 09:01", "2000-01-01 09:05"], freq="T"
)
other5 = PeriodIndex(["2000-01-01 09:01", "2000-01-01 09:05"], freq="T")
expected5 = PeriodIndex(["2000-01-01 09:03"], freq="T")
period_rng = [
"2000-02-01",
"2000-01-01",
"2000-06-01",
"2000-07-01",
"2000-05-01",
"2000-03-01",
"2000-04-01",
]
rng6 = PeriodIndex(period_rng, freq="M")
other6 = period_range("2000-04-01", freq="M", periods=7)
expected6 = PeriodIndex(["2000-02-01", "2000-01-01", "2000-03-01"], freq="M")
period_rng = ["2003", "2007", "2006", "2005", "2004"]
rng7 = PeriodIndex(period_rng, freq="A")
other7 = period_range("1998-01-01", freq="A", periods=8)
expected7 = PeriodIndex(["2007", "2006"], freq="A")
for rng, other, expected in [
(rng1, other1, expected1),
(rng2, other2, expected2),
(rng3, other3, expected3),
(rng4, other4, expected4),
(rng5, other5, expected5),
(rng6, other6, expected6),
(rng7, other7, expected7),
]:
result_difference = rng.difference(other, sort=sort)
if sort is None and len(other):
# We dont sort (yet?) when empty GH#24959
expected = expected.sort_values()
tm.assert_index_equal(result_difference, expected)
def test_difference_freq(self, sort):
# GH14323: difference of Period MUST preserve frequency
# but the ability to union results must be preserved
index = period_range("20160920", "20160925", freq="D")
other = period_range("20160921", "20160924", freq="D")
expected = PeriodIndex(["20160920", "20160925"], freq="D")
idx_diff = index.difference(other, sort)
tm.assert_index_equal(idx_diff, expected)
tm.assert_attr_equal("freq", idx_diff, expected)
other = period_range("20160922", "20160925", freq="D")
idx_diff = index.difference(other, sort)
expected = PeriodIndex(["20160920", "20160921"], freq="D")
tm.assert_index_equal(idx_diff, expected)
tm.assert_attr_equal("freq", idx_diff, expected)
def test_intersection_equal_duplicates(self):
# GH#38302
idx = period_range("2011-01-01", periods=2)
idx_dup = idx.append(idx)
result = idx_dup.intersection(idx_dup)
tm.assert_index_equal(result, idx)
def test_union_duplicates(self):
# GH#36289
idx = period_range("2011-01-01", periods=2)
idx_dup = idx.append(idx)
idx2 = period_range("2011-01-02", periods=2)
idx2_dup = idx2.append(idx2)
result = idx_dup.union(idx2_dup)
expected = PeriodIndex(
[
"2011-01-01",
"2011-01-01",
"2011-01-02",
"2011-01-02",
"2011-01-03",
"2011-01-03",
],
freq="D",
)
tm.assert_index_equal(result, expected)

View File

@ -0,0 +1,42 @@
import numpy as np
import pytest
from pandas import (
Period,
PeriodIndex,
period_range,
)
import pandas._testing as tm
class TestPeriodRepresentation:
"""
Wish to match NumPy units
"""
def _check_freq(self, freq, base_date):
rng = period_range(start=base_date, periods=10, freq=freq)
exp = np.arange(10, dtype=np.int64)
tm.assert_numpy_array_equal(rng.asi8, exp)
def test_annual(self):
self._check_freq("A", 1970)
def test_monthly(self):
self._check_freq("M", "1970-01")
@pytest.mark.parametrize("freq", ["W-THU", "D", "B", "H", "T", "S", "L", "U", "N"])
def test_freq(self, freq):
self._check_freq(freq, "1970-01-01")
class TestPeriodIndexConversion:
def test_tolist(self):
index = period_range(freq="A", start="1/1/2001", end="12/1/2009")
rs = index.tolist()
for x in rs:
assert isinstance(x, Period)
recon = PeriodIndex(rs)
tm.assert_index_equal(index, recon)