mirror of
https://github.com/aykhans/AzSuicideDataVisualization.git
synced 2025-07-04 07:08:05 +00:00
first commit
This commit is contained in:
@ -0,0 +1,328 @@
|
||||
from datetime import datetime
|
||||
|
||||
import dateutil
|
||||
import numpy as np
|
||||
import pytest
|
||||
import pytz
|
||||
|
||||
import pandas as pd
|
||||
from pandas import (
|
||||
DatetimeIndex,
|
||||
Index,
|
||||
NaT,
|
||||
PeriodIndex,
|
||||
Timestamp,
|
||||
date_range,
|
||||
)
|
||||
import pandas._testing as tm
|
||||
from pandas.core.api import (
|
||||
Int64Index,
|
||||
UInt64Index,
|
||||
)
|
||||
|
||||
|
||||
class TestDatetimeIndex:
|
||||
def test_astype(self):
|
||||
# GH 13149, GH 13209
|
||||
idx = DatetimeIndex(["2016-05-16", "NaT", NaT, np.NaN], name="idx")
|
||||
|
||||
result = idx.astype(object)
|
||||
expected = Index(
|
||||
[Timestamp("2016-05-16")] + [NaT] * 3, dtype=object, name="idx"
|
||||
)
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
result = idx.astype(int)
|
||||
expected = Int64Index(
|
||||
[1463356800000000000] + [-9223372036854775808] * 3,
|
||||
dtype=np.int64,
|
||||
name="idx",
|
||||
)
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
rng = date_range("1/1/2000", periods=10, name="idx")
|
||||
result = rng.astype("i8")
|
||||
tm.assert_index_equal(result, Index(rng.asi8, name="idx"))
|
||||
tm.assert_numpy_array_equal(result.values, rng.asi8)
|
||||
|
||||
def test_astype_uint(self):
|
||||
arr = date_range("2000", periods=2, name="idx")
|
||||
expected = UInt64Index(
|
||||
np.array([946684800000000000, 946771200000000000], dtype="uint64"),
|
||||
name="idx",
|
||||
)
|
||||
tm.assert_index_equal(arr.astype("uint64"), expected)
|
||||
tm.assert_index_equal(arr.astype("uint32"), expected)
|
||||
|
||||
def test_astype_with_tz(self):
|
||||
|
||||
# with tz
|
||||
rng = date_range("1/1/2000", periods=10, tz="US/Eastern")
|
||||
with tm.assert_produces_warning(FutureWarning):
|
||||
# deprecated
|
||||
result = rng.astype("datetime64[ns]")
|
||||
with tm.assert_produces_warning(FutureWarning):
|
||||
# check DatetimeArray while we're here deprecated
|
||||
rng._data.astype("datetime64[ns]")
|
||||
|
||||
expected = (
|
||||
date_range("1/1/2000", periods=10, tz="US/Eastern")
|
||||
.tz_convert("UTC")
|
||||
.tz_localize(None)
|
||||
)
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
def test_astype_tzaware_to_tzaware(self):
|
||||
# GH 18951: tz-aware to tz-aware
|
||||
idx = date_range("20170101", periods=4, tz="US/Pacific")
|
||||
result = idx.astype("datetime64[ns, US/Eastern]")
|
||||
expected = date_range("20170101 03:00:00", periods=4, tz="US/Eastern")
|
||||
tm.assert_index_equal(result, expected)
|
||||
assert result.freq == expected.freq
|
||||
|
||||
def test_astype_tznaive_to_tzaware(self):
|
||||
# GH 18951: tz-naive to tz-aware
|
||||
idx = date_range("20170101", periods=4)
|
||||
idx = idx._with_freq(None) # tz_localize does not preserve freq
|
||||
with tm.assert_produces_warning(FutureWarning):
|
||||
# dt64->dt64tz deprecated
|
||||
result = idx.astype("datetime64[ns, US/Eastern]")
|
||||
with tm.assert_produces_warning(FutureWarning):
|
||||
# dt64->dt64tz deprecated
|
||||
idx._data.astype("datetime64[ns, US/Eastern]")
|
||||
|
||||
expected = date_range("20170101", periods=4, tz="US/Eastern")
|
||||
expected = expected._with_freq(None)
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
def test_astype_str_nat(self):
|
||||
# GH 13149, GH 13209
|
||||
# verify that we are returning NaT as a string (and not unicode)
|
||||
|
||||
idx = DatetimeIndex(["2016-05-16", "NaT", NaT, np.NaN])
|
||||
result = idx.astype(str)
|
||||
expected = Index(["2016-05-16", "NaT", "NaT", "NaT"], dtype=object)
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
def test_astype_str(self):
|
||||
# test astype string - #10442
|
||||
dti = date_range("2012-01-01", periods=4, name="test_name")
|
||||
result = dti.astype(str)
|
||||
expected = Index(
|
||||
["2012-01-01", "2012-01-02", "2012-01-03", "2012-01-04"],
|
||||
name="test_name",
|
||||
dtype=object,
|
||||
)
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
def test_astype_str_tz_and_name(self):
|
||||
# test astype string with tz and name
|
||||
dti = date_range("2012-01-01", periods=3, name="test_name", tz="US/Eastern")
|
||||
result = dti.astype(str)
|
||||
expected = Index(
|
||||
[
|
||||
"2012-01-01 00:00:00-05:00",
|
||||
"2012-01-02 00:00:00-05:00",
|
||||
"2012-01-03 00:00:00-05:00",
|
||||
],
|
||||
name="test_name",
|
||||
dtype=object,
|
||||
)
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
def test_astype_str_freq_and_name(self):
|
||||
# test astype string with freqH and name
|
||||
dti = date_range("1/1/2011", periods=3, freq="H", name="test_name")
|
||||
result = dti.astype(str)
|
||||
expected = Index(
|
||||
["2011-01-01 00:00:00", "2011-01-01 01:00:00", "2011-01-01 02:00:00"],
|
||||
name="test_name",
|
||||
dtype=object,
|
||||
)
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
def test_astype_str_freq_and_tz(self):
|
||||
# test astype string with freqH and timezone
|
||||
dti = date_range(
|
||||
"3/6/2012 00:00", periods=2, freq="H", tz="Europe/London", name="test_name"
|
||||
)
|
||||
result = dti.astype(str)
|
||||
expected = Index(
|
||||
["2012-03-06 00:00:00+00:00", "2012-03-06 01:00:00+00:00"],
|
||||
dtype=object,
|
||||
name="test_name",
|
||||
)
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
def test_astype_datetime64(self):
|
||||
# GH 13149, GH 13209
|
||||
idx = DatetimeIndex(["2016-05-16", "NaT", NaT, np.NaN], name="idx")
|
||||
|
||||
result = idx.astype("datetime64[ns]")
|
||||
tm.assert_index_equal(result, idx)
|
||||
assert result is not idx
|
||||
|
||||
result = idx.astype("datetime64[ns]", copy=False)
|
||||
tm.assert_index_equal(result, idx)
|
||||
assert result is idx
|
||||
|
||||
idx_tz = DatetimeIndex(["2016-05-16", "NaT", NaT, np.NaN], tz="EST", name="idx")
|
||||
with tm.assert_produces_warning(FutureWarning):
|
||||
# dt64tz->dt64 deprecated
|
||||
result = idx_tz.astype("datetime64[ns]")
|
||||
expected = DatetimeIndex(
|
||||
["2016-05-16 05:00:00", "NaT", "NaT", "NaT"],
|
||||
dtype="datetime64[ns]",
|
||||
name="idx",
|
||||
)
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
def test_astype_object(self):
|
||||
rng = date_range("1/1/2000", periods=20)
|
||||
|
||||
casted = rng.astype("O")
|
||||
exp_values = list(rng)
|
||||
|
||||
tm.assert_index_equal(casted, Index(exp_values, dtype=np.object_))
|
||||
assert casted.tolist() == exp_values
|
||||
|
||||
@pytest.mark.parametrize("tz", [None, "Asia/Tokyo"])
|
||||
def test_astype_object_tz(self, tz):
|
||||
idx = date_range(start="2013-01-01", periods=4, freq="M", name="idx", tz=tz)
|
||||
expected_list = [
|
||||
Timestamp("2013-01-31", tz=tz),
|
||||
Timestamp("2013-02-28", tz=tz),
|
||||
Timestamp("2013-03-31", tz=tz),
|
||||
Timestamp("2013-04-30", tz=tz),
|
||||
]
|
||||
expected = Index(expected_list, dtype=object, name="idx")
|
||||
result = idx.astype(object)
|
||||
tm.assert_index_equal(result, expected)
|
||||
assert idx.tolist() == expected_list
|
||||
|
||||
def test_astype_object_with_nat(self):
|
||||
idx = DatetimeIndex(
|
||||
[datetime(2013, 1, 1), datetime(2013, 1, 2), NaT, datetime(2013, 1, 4)],
|
||||
name="idx",
|
||||
)
|
||||
expected_list = [
|
||||
Timestamp("2013-01-01"),
|
||||
Timestamp("2013-01-02"),
|
||||
NaT,
|
||||
Timestamp("2013-01-04"),
|
||||
]
|
||||
expected = Index(expected_list, dtype=object, name="idx")
|
||||
result = idx.astype(object)
|
||||
tm.assert_index_equal(result, expected)
|
||||
assert idx.tolist() == expected_list
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"dtype",
|
||||
[float, "timedelta64", "timedelta64[ns]", "datetime64", "datetime64[D]"],
|
||||
)
|
||||
def test_astype_raises(self, dtype):
|
||||
# GH 13149, GH 13209
|
||||
idx = DatetimeIndex(["2016-05-16", "NaT", NaT, np.NaN])
|
||||
msg = "Cannot cast DatetimeIndex to dtype"
|
||||
with pytest.raises(TypeError, match=msg):
|
||||
idx.astype(dtype)
|
||||
|
||||
def test_index_convert_to_datetime_array(self):
|
||||
def _check_rng(rng):
|
||||
converted = rng.to_pydatetime()
|
||||
assert isinstance(converted, np.ndarray)
|
||||
for x, stamp in zip(converted, rng):
|
||||
assert isinstance(x, datetime)
|
||||
assert x == stamp.to_pydatetime()
|
||||
assert x.tzinfo == stamp.tzinfo
|
||||
|
||||
rng = date_range("20090415", "20090519")
|
||||
rng_eastern = date_range("20090415", "20090519", tz="US/Eastern")
|
||||
rng_utc = date_range("20090415", "20090519", tz="utc")
|
||||
|
||||
_check_rng(rng)
|
||||
_check_rng(rng_eastern)
|
||||
_check_rng(rng_utc)
|
||||
|
||||
def test_index_convert_to_datetime_array_explicit_pytz(self):
|
||||
def _check_rng(rng):
|
||||
converted = rng.to_pydatetime()
|
||||
assert isinstance(converted, np.ndarray)
|
||||
for x, stamp in zip(converted, rng):
|
||||
assert isinstance(x, datetime)
|
||||
assert x == stamp.to_pydatetime()
|
||||
assert x.tzinfo == stamp.tzinfo
|
||||
|
||||
rng = date_range("20090415", "20090519")
|
||||
rng_eastern = date_range("20090415", "20090519", tz=pytz.timezone("US/Eastern"))
|
||||
rng_utc = date_range("20090415", "20090519", tz=pytz.utc)
|
||||
|
||||
_check_rng(rng)
|
||||
_check_rng(rng_eastern)
|
||||
_check_rng(rng_utc)
|
||||
|
||||
def test_index_convert_to_datetime_array_dateutil(self):
|
||||
def _check_rng(rng):
|
||||
converted = rng.to_pydatetime()
|
||||
assert isinstance(converted, np.ndarray)
|
||||
for x, stamp in zip(converted, rng):
|
||||
assert isinstance(x, datetime)
|
||||
assert x == stamp.to_pydatetime()
|
||||
assert x.tzinfo == stamp.tzinfo
|
||||
|
||||
rng = date_range("20090415", "20090519")
|
||||
rng_eastern = date_range("20090415", "20090519", tz="dateutil/US/Eastern")
|
||||
rng_utc = date_range("20090415", "20090519", tz=dateutil.tz.tzutc())
|
||||
|
||||
_check_rng(rng)
|
||||
_check_rng(rng_eastern)
|
||||
_check_rng(rng_utc)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"tz, dtype",
|
||||
[["US/Pacific", "datetime64[ns, US/Pacific]"], [None, "datetime64[ns]"]],
|
||||
)
|
||||
def test_integer_index_astype_datetime(self, tz, dtype):
|
||||
# GH 20997, 20964, 24559
|
||||
val = [Timestamp("2018-01-01", tz=tz).value]
|
||||
result = Index(val, name="idx").astype(dtype)
|
||||
expected = DatetimeIndex(["2018-01-01"], tz=tz, name="idx")
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
def test_dti_astype_period(self):
|
||||
idx = DatetimeIndex([NaT, "2011-01-01", "2011-02-01"], name="idx")
|
||||
|
||||
res = idx.astype("period[M]")
|
||||
exp = PeriodIndex(["NaT", "2011-01", "2011-02"], freq="M", name="idx")
|
||||
tm.assert_index_equal(res, exp)
|
||||
|
||||
res = idx.astype("period[3M]")
|
||||
exp = PeriodIndex(["NaT", "2011-01", "2011-02"], freq="3M", name="idx")
|
||||
tm.assert_index_equal(res, exp)
|
||||
|
||||
|
||||
class TestAstype:
|
||||
@pytest.mark.parametrize("tz", [None, "US/Central"])
|
||||
def test_astype_category(self, tz):
|
||||
obj = date_range("2000", periods=2, tz=tz, name="idx")
|
||||
result = obj.astype("category")
|
||||
expected = pd.CategoricalIndex(
|
||||
[Timestamp("2000-01-01", tz=tz), Timestamp("2000-01-02", tz=tz)],
|
||||
name="idx",
|
||||
)
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
result = obj._data.astype("category")
|
||||
expected = expected.values
|
||||
tm.assert_categorical_equal(result, expected)
|
||||
|
||||
@pytest.mark.parametrize("tz", [None, "US/Central"])
|
||||
def test_astype_array_fallback(self, tz):
|
||||
obj = date_range("2000", periods=2, tz=tz, 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)
|
@ -0,0 +1,107 @@
|
||||
import numpy as np
|
||||
|
||||
from pandas import (
|
||||
DatetimeIndex,
|
||||
Index,
|
||||
date_range,
|
||||
factorize,
|
||||
)
|
||||
import pandas._testing as tm
|
||||
|
||||
|
||||
class TestDatetimeIndexFactorize:
|
||||
def test_factorize(self):
|
||||
idx1 = DatetimeIndex(
|
||||
["2014-01", "2014-01", "2014-02", "2014-02", "2014-03", "2014-03"]
|
||||
)
|
||||
|
||||
exp_arr = np.array([0, 0, 1, 1, 2, 2], dtype=np.intp)
|
||||
exp_idx = DatetimeIndex(["2014-01", "2014-02", "2014-03"])
|
||||
|
||||
arr, idx = idx1.factorize()
|
||||
tm.assert_numpy_array_equal(arr, exp_arr)
|
||||
tm.assert_index_equal(idx, exp_idx)
|
||||
assert idx.freq == exp_idx.freq
|
||||
|
||||
arr, idx = idx1.factorize(sort=True)
|
||||
tm.assert_numpy_array_equal(arr, exp_arr)
|
||||
tm.assert_index_equal(idx, exp_idx)
|
||||
assert idx.freq == exp_idx.freq
|
||||
|
||||
# tz must be preserved
|
||||
idx1 = idx1.tz_localize("Asia/Tokyo")
|
||||
exp_idx = exp_idx.tz_localize("Asia/Tokyo")
|
||||
|
||||
arr, idx = idx1.factorize()
|
||||
tm.assert_numpy_array_equal(arr, exp_arr)
|
||||
tm.assert_index_equal(idx, exp_idx)
|
||||
assert idx.freq == exp_idx.freq
|
||||
|
||||
idx2 = DatetimeIndex(
|
||||
["2014-03", "2014-03", "2014-02", "2014-01", "2014-03", "2014-01"]
|
||||
)
|
||||
|
||||
exp_arr = np.array([2, 2, 1, 0, 2, 0], dtype=np.intp)
|
||||
exp_idx = DatetimeIndex(["2014-01", "2014-02", "2014-03"])
|
||||
arr, idx = idx2.factorize(sort=True)
|
||||
tm.assert_numpy_array_equal(arr, exp_arr)
|
||||
tm.assert_index_equal(idx, exp_idx)
|
||||
assert idx.freq == exp_idx.freq
|
||||
|
||||
exp_arr = np.array([0, 0, 1, 2, 0, 2], dtype=np.intp)
|
||||
exp_idx = DatetimeIndex(["2014-03", "2014-02", "2014-01"])
|
||||
arr, idx = idx2.factorize()
|
||||
tm.assert_numpy_array_equal(arr, exp_arr)
|
||||
tm.assert_index_equal(idx, exp_idx)
|
||||
assert idx.freq == exp_idx.freq
|
||||
|
||||
def test_factorize_preserves_freq(self):
|
||||
# GH#38120 freq should be preserved
|
||||
idx3 = date_range("2000-01", periods=4, freq="M", tz="Asia/Tokyo")
|
||||
exp_arr = np.array([0, 1, 2, 3], dtype=np.intp)
|
||||
|
||||
arr, idx = idx3.factorize()
|
||||
tm.assert_numpy_array_equal(arr, exp_arr)
|
||||
tm.assert_index_equal(idx, idx3)
|
||||
assert idx.freq == idx3.freq
|
||||
|
||||
arr, idx = factorize(idx3)
|
||||
tm.assert_numpy_array_equal(arr, exp_arr)
|
||||
tm.assert_index_equal(idx, idx3)
|
||||
assert idx.freq == idx3.freq
|
||||
|
||||
def test_factorize_tz(self, tz_naive_fixture, index_or_series):
|
||||
tz = tz_naive_fixture
|
||||
# GH#13750
|
||||
base = date_range("2016-11-05", freq="H", periods=100, tz=tz)
|
||||
idx = base.repeat(5)
|
||||
|
||||
exp_arr = np.arange(100, dtype=np.intp).repeat(5)
|
||||
|
||||
obj = index_or_series(idx)
|
||||
|
||||
arr, res = obj.factorize()
|
||||
tm.assert_numpy_array_equal(arr, exp_arr)
|
||||
expected = base._with_freq(None)
|
||||
tm.assert_index_equal(res, expected)
|
||||
assert res.freq == expected.freq
|
||||
|
||||
def test_factorize_dst(self, index_or_series):
|
||||
# GH#13750
|
||||
idx = date_range("2016-11-06", freq="H", periods=12, tz="US/Eastern")
|
||||
obj = index_or_series(idx)
|
||||
|
||||
arr, res = obj.factorize()
|
||||
tm.assert_numpy_array_equal(arr, np.arange(12, dtype=np.intp))
|
||||
tm.assert_index_equal(res, idx)
|
||||
if index_or_series is Index:
|
||||
assert res.freq == idx.freq
|
||||
|
||||
idx = date_range("2016-06-13", freq="H", periods=12, tz="US/Eastern")
|
||||
obj = index_or_series(idx)
|
||||
|
||||
arr, res = obj.factorize()
|
||||
tm.assert_numpy_array_equal(arr, np.arange(12, dtype=np.intp))
|
||||
tm.assert_index_equal(res, idx)
|
||||
if index_or_series is Index:
|
||||
assert res.freq == idx.freq
|
@ -0,0 +1,62 @@
|
||||
import pytest
|
||||
|
||||
import pandas as pd
|
||||
import pandas._testing as tm
|
||||
|
||||
|
||||
class TestDatetimeIndexFillNA:
|
||||
@pytest.mark.parametrize("tz", ["US/Eastern", "Asia/Tokyo"])
|
||||
def test_fillna_datetime64(self, tz):
|
||||
# GH 11343
|
||||
idx = pd.DatetimeIndex(["2011-01-01 09:00", pd.NaT, "2011-01-01 11:00"])
|
||||
|
||||
exp = pd.DatetimeIndex(
|
||||
["2011-01-01 09:00", "2011-01-01 10:00", "2011-01-01 11:00"]
|
||||
)
|
||||
tm.assert_index_equal(idx.fillna(pd.Timestamp("2011-01-01 10:00")), exp)
|
||||
|
||||
# tz mismatch
|
||||
exp = pd.Index(
|
||||
[
|
||||
pd.Timestamp("2011-01-01 09:00"),
|
||||
pd.Timestamp("2011-01-01 10:00", tz=tz),
|
||||
pd.Timestamp("2011-01-01 11:00"),
|
||||
],
|
||||
dtype=object,
|
||||
)
|
||||
tm.assert_index_equal(idx.fillna(pd.Timestamp("2011-01-01 10:00", tz=tz)), exp)
|
||||
|
||||
# object
|
||||
exp = pd.Index(
|
||||
[pd.Timestamp("2011-01-01 09:00"), "x", pd.Timestamp("2011-01-01 11:00")],
|
||||
dtype=object,
|
||||
)
|
||||
tm.assert_index_equal(idx.fillna("x"), exp)
|
||||
|
||||
idx = pd.DatetimeIndex(["2011-01-01 09:00", pd.NaT, "2011-01-01 11:00"], tz=tz)
|
||||
|
||||
exp = pd.DatetimeIndex(
|
||||
["2011-01-01 09:00", "2011-01-01 10:00", "2011-01-01 11:00"], tz=tz
|
||||
)
|
||||
tm.assert_index_equal(idx.fillna(pd.Timestamp("2011-01-01 10:00", tz=tz)), exp)
|
||||
|
||||
exp = pd.Index(
|
||||
[
|
||||
pd.Timestamp("2011-01-01 09:00", tz=tz),
|
||||
pd.Timestamp("2011-01-01 10:00"),
|
||||
pd.Timestamp("2011-01-01 11:00", tz=tz),
|
||||
],
|
||||
dtype=object,
|
||||
)
|
||||
tm.assert_index_equal(idx.fillna(pd.Timestamp("2011-01-01 10:00")), exp)
|
||||
|
||||
# object
|
||||
exp = pd.Index(
|
||||
[
|
||||
pd.Timestamp("2011-01-01 09:00", tz=tz),
|
||||
"x",
|
||||
pd.Timestamp("2011-01-01 11:00", tz=tz),
|
||||
],
|
||||
dtype=object,
|
||||
)
|
||||
tm.assert_index_equal(idx.fillna("x"), exp)
|
@ -0,0 +1,267 @@
|
||||
from datetime import datetime
|
||||
|
||||
import numpy as np
|
||||
import pytest
|
||||
import pytz
|
||||
|
||||
from pandas import (
|
||||
NA,
|
||||
DatetimeIndex,
|
||||
Index,
|
||||
NaT,
|
||||
Timestamp,
|
||||
date_range,
|
||||
)
|
||||
import pandas._testing as tm
|
||||
|
||||
|
||||
class TestInsert:
|
||||
@pytest.mark.parametrize("null", [None, np.nan, np.datetime64("NaT"), NaT, NA])
|
||||
@pytest.mark.parametrize("tz", [None, "UTC", "US/Eastern"])
|
||||
def test_insert_nat(self, tz, null):
|
||||
# GH#16537, GH#18295 (test missing)
|
||||
|
||||
idx = DatetimeIndex(["2017-01-01"], tz=tz)
|
||||
expected = DatetimeIndex(["NaT", "2017-01-01"], tz=tz)
|
||||
if tz is not None and isinstance(null, np.datetime64):
|
||||
expected = Index([null, idx[0]], dtype=object)
|
||||
|
||||
res = idx.insert(0, null)
|
||||
tm.assert_index_equal(res, expected)
|
||||
|
||||
@pytest.mark.parametrize("tz", [None, "UTC", "US/Eastern"])
|
||||
def test_insert_invalid_na(self, tz):
|
||||
idx = DatetimeIndex(["2017-01-01"], tz=tz)
|
||||
|
||||
item = np.timedelta64("NaT")
|
||||
result = idx.insert(0, item)
|
||||
expected = Index([item] + list(idx), dtype=object)
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
def test_insert_empty_preserves_freq(self, tz_naive_fixture):
|
||||
# GH#33573
|
||||
tz = tz_naive_fixture
|
||||
dti = DatetimeIndex([], tz=tz, freq="D")
|
||||
item = Timestamp("2017-04-05").tz_localize(tz)
|
||||
|
||||
result = dti.insert(0, item)
|
||||
assert result.freq == dti.freq
|
||||
|
||||
# But not when we insert an item that doesn't conform to freq
|
||||
dti = DatetimeIndex([], tz=tz, freq="W-THU")
|
||||
result = dti.insert(0, item)
|
||||
assert result.freq is None
|
||||
|
||||
def test_insert(self):
|
||||
idx = DatetimeIndex(["2000-01-04", "2000-01-01", "2000-01-02"], name="idx")
|
||||
|
||||
result = idx.insert(2, datetime(2000, 1, 5))
|
||||
exp = DatetimeIndex(
|
||||
["2000-01-04", "2000-01-01", "2000-01-05", "2000-01-02"], name="idx"
|
||||
)
|
||||
tm.assert_index_equal(result, exp)
|
||||
|
||||
# insertion of non-datetime should coerce to object index
|
||||
result = idx.insert(1, "inserted")
|
||||
expected = Index(
|
||||
[
|
||||
datetime(2000, 1, 4),
|
||||
"inserted",
|
||||
datetime(2000, 1, 1),
|
||||
datetime(2000, 1, 2),
|
||||
],
|
||||
name="idx",
|
||||
)
|
||||
assert not isinstance(result, DatetimeIndex)
|
||||
tm.assert_index_equal(result, expected)
|
||||
assert result.name == expected.name
|
||||
|
||||
idx = date_range("1/1/2000", periods=3, freq="M", name="idx")
|
||||
|
||||
# preserve freq
|
||||
expected_0 = DatetimeIndex(
|
||||
["1999-12-31", "2000-01-31", "2000-02-29", "2000-03-31"],
|
||||
name="idx",
|
||||
freq="M",
|
||||
)
|
||||
expected_3 = DatetimeIndex(
|
||||
["2000-01-31", "2000-02-29", "2000-03-31", "2000-04-30"],
|
||||
name="idx",
|
||||
freq="M",
|
||||
)
|
||||
|
||||
# reset freq to None
|
||||
expected_1_nofreq = DatetimeIndex(
|
||||
["2000-01-31", "2000-01-31", "2000-02-29", "2000-03-31"],
|
||||
name="idx",
|
||||
freq=None,
|
||||
)
|
||||
expected_3_nofreq = DatetimeIndex(
|
||||
["2000-01-31", "2000-02-29", "2000-03-31", "2000-01-02"],
|
||||
name="idx",
|
||||
freq=None,
|
||||
)
|
||||
|
||||
cases = [
|
||||
(0, datetime(1999, 12, 31), expected_0),
|
||||
(-3, datetime(1999, 12, 31), expected_0),
|
||||
(3, datetime(2000, 4, 30), expected_3),
|
||||
(1, datetime(2000, 1, 31), expected_1_nofreq),
|
||||
(3, datetime(2000, 1, 2), expected_3_nofreq),
|
||||
]
|
||||
|
||||
for n, d, expected in cases:
|
||||
result = idx.insert(n, d)
|
||||
tm.assert_index_equal(result, expected)
|
||||
assert result.name == expected.name
|
||||
assert result.freq == expected.freq
|
||||
|
||||
# reset freq to None
|
||||
result = idx.insert(3, datetime(2000, 1, 2))
|
||||
expected = DatetimeIndex(
|
||||
["2000-01-31", "2000-02-29", "2000-03-31", "2000-01-02"],
|
||||
name="idx",
|
||||
freq=None,
|
||||
)
|
||||
tm.assert_index_equal(result, expected)
|
||||
assert result.name == expected.name
|
||||
assert result.freq is None
|
||||
|
||||
for tz in ["US/Pacific", "Asia/Singapore"]:
|
||||
idx = date_range("1/1/2000 09:00", periods=6, freq="H", tz=tz, name="idx")
|
||||
# preserve freq
|
||||
expected = date_range(
|
||||
"1/1/2000 09:00", periods=7, freq="H", tz=tz, name="idx"
|
||||
)
|
||||
for d in [
|
||||
Timestamp("2000-01-01 15:00", tz=tz),
|
||||
pytz.timezone(tz).localize(datetime(2000, 1, 1, 15)),
|
||||
]:
|
||||
|
||||
result = idx.insert(6, d)
|
||||
tm.assert_index_equal(result, expected)
|
||||
assert result.name == expected.name
|
||||
assert result.freq == expected.freq
|
||||
assert result.tz == expected.tz
|
||||
|
||||
expected = DatetimeIndex(
|
||||
[
|
||||
"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-01 14:00",
|
||||
"2000-01-01 10:00",
|
||||
],
|
||||
name="idx",
|
||||
tz=tz,
|
||||
freq=None,
|
||||
)
|
||||
# reset freq to None
|
||||
for d in [
|
||||
Timestamp("2000-01-01 10:00", tz=tz),
|
||||
pytz.timezone(tz).localize(datetime(2000, 1, 1, 10)),
|
||||
]:
|
||||
result = idx.insert(6, d)
|
||||
tm.assert_index_equal(result, expected)
|
||||
assert result.name == expected.name
|
||||
assert result.tz == expected.tz
|
||||
assert result.freq is None
|
||||
|
||||
# TODO: also changes DataFrame.__setitem__ with expansion
|
||||
def test_insert_mismatched_tzawareness(self):
|
||||
# see GH#7299
|
||||
idx = date_range("1/1/2000", periods=3, freq="D", tz="Asia/Tokyo", name="idx")
|
||||
|
||||
# mismatched tz-awareness
|
||||
item = Timestamp("2000-01-04")
|
||||
result = idx.insert(3, item)
|
||||
expected = Index(
|
||||
list(idx[:3]) + [item] + list(idx[3:]), dtype=object, name="idx"
|
||||
)
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
# mismatched tz-awareness
|
||||
item = datetime(2000, 1, 4)
|
||||
result = idx.insert(3, item)
|
||||
expected = Index(
|
||||
list(idx[:3]) + [item] + list(idx[3:]), dtype=object, name="idx"
|
||||
)
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
# TODO: also changes DataFrame.__setitem__ with expansion
|
||||
def test_insert_mismatched_tz(self):
|
||||
# see GH#7299
|
||||
idx = date_range("1/1/2000", periods=3, freq="D", tz="Asia/Tokyo", name="idx")
|
||||
|
||||
# mismatched tz -> cast to object (could reasonably cast to same tz or UTC)
|
||||
item = Timestamp("2000-01-04", tz="US/Eastern")
|
||||
with tm.assert_produces_warning(FutureWarning, match="mismatched timezone"):
|
||||
result = idx.insert(3, item)
|
||||
expected = Index(
|
||||
list(idx[:3]) + [item] + list(idx[3:]),
|
||||
dtype=object,
|
||||
# once deprecation is enforced
|
||||
# list(idx[:3]) + [item.tz_convert(idx.tz)] + list(idx[3:]),
|
||||
name="idx",
|
||||
)
|
||||
# once deprecation is enforced
|
||||
# assert expected.dtype == idx.dtype
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
# mismatched tz -> cast to object (could reasonably cast to same tz)
|
||||
item = datetime(2000, 1, 4, tzinfo=pytz.timezone("US/Eastern"))
|
||||
with tm.assert_produces_warning(FutureWarning, match="mismatched timezone"):
|
||||
result = idx.insert(3, item)
|
||||
expected = Index(
|
||||
list(idx[:3]) + [item] + list(idx[3:]),
|
||||
dtype=object,
|
||||
# once deprecation is enforced
|
||||
# list(idx[:3]) + [item.astimezone(idx.tzinfo)] + list(idx[3:]),
|
||||
name="idx",
|
||||
)
|
||||
# once deprecation is enforced
|
||||
# assert expected.dtype == idx.dtype
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"item", [0, np.int64(0), np.float64(0), np.array(0), np.timedelta64(456)]
|
||||
)
|
||||
def test_insert_mismatched_types_raises(self, tz_aware_fixture, item):
|
||||
# GH#33703 dont cast these to dt64
|
||||
tz = tz_aware_fixture
|
||||
dti = date_range("2019-11-04", periods=9, freq="-1D", name=9, tz=tz)
|
||||
|
||||
result = dti.insert(1, item)
|
||||
|
||||
if isinstance(item, np.ndarray):
|
||||
assert item.item() == 0
|
||||
expected = Index([dti[0], 0] + list(dti[1:]), dtype=object, name=9)
|
||||
else:
|
||||
expected = Index([dti[0], item] + list(dti[1:]), dtype=object, name=9)
|
||||
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
def test_insert_castable_str(self, tz_aware_fixture):
|
||||
# GH#33703
|
||||
tz = tz_aware_fixture
|
||||
dti = date_range("2019-11-04", periods=3, freq="-1D", name=9, tz=tz)
|
||||
|
||||
value = "2019-11-05"
|
||||
result = dti.insert(0, value)
|
||||
|
||||
ts = Timestamp(value).tz_localize(tz)
|
||||
expected = DatetimeIndex([ts] + list(dti), dtype=dti.dtype, name=9)
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
def test_insert_non_castable_str(self, tz_aware_fixture):
|
||||
# GH#33703
|
||||
tz = tz_aware_fixture
|
||||
dti = date_range("2019-11-04", periods=3, freq="-1D", name=9, tz=tz)
|
||||
|
||||
value = "foo"
|
||||
result = dti.insert(0, value)
|
||||
|
||||
expected = Index(["foo"] + list(dti), dtype=object, name=9)
|
||||
tm.assert_index_equal(result, expected)
|
@ -0,0 +1,20 @@
|
||||
from pandas import (
|
||||
DataFrame,
|
||||
DatetimeIndex,
|
||||
)
|
||||
import pandas._testing as tm
|
||||
|
||||
|
||||
def test_isocalendar_returns_correct_values_close_to_new_year_with_tz():
|
||||
# GH#6538: Check that DatetimeIndex and its TimeStamp elements
|
||||
# return the same weekofyear accessor close to new year w/ tz
|
||||
dates = ["2013/12/29", "2013/12/30", "2013/12/31"]
|
||||
dates = DatetimeIndex(dates, tz="Europe/Brussels")
|
||||
result = dates.isocalendar()
|
||||
expected_data_frame = DataFrame(
|
||||
[[2013, 52, 7], [2014, 1, 1], [2014, 1, 2]],
|
||||
columns=["year", "week", "day"],
|
||||
index=dates,
|
||||
dtype="UInt32",
|
||||
)
|
||||
tm.assert_frame_equal(result, expected_data_frame)
|
@ -0,0 +1,78 @@
|
||||
import numpy as np
|
||||
import pytest
|
||||
|
||||
from pandas import (
|
||||
DatetimeIndex,
|
||||
Timestamp,
|
||||
date_range,
|
||||
)
|
||||
import pandas._testing as tm
|
||||
|
||||
|
||||
class TestRepeat:
|
||||
def test_repeat_range(self, tz_naive_fixture):
|
||||
tz = tz_naive_fixture
|
||||
rng = date_range("1/1/2000", "1/1/2001")
|
||||
|
||||
result = rng.repeat(5)
|
||||
assert result.freq is None
|
||||
assert len(result) == 5 * len(rng)
|
||||
|
||||
index = date_range("2001-01-01", periods=2, freq="D", tz=tz)
|
||||
exp = DatetimeIndex(
|
||||
["2001-01-01", "2001-01-01", "2001-01-02", "2001-01-02"], tz=tz
|
||||
)
|
||||
for res in [index.repeat(2), np.repeat(index, 2)]:
|
||||
tm.assert_index_equal(res, exp)
|
||||
assert res.freq is None
|
||||
|
||||
index = date_range("2001-01-01", periods=2, freq="2D", tz=tz)
|
||||
exp = DatetimeIndex(
|
||||
["2001-01-01", "2001-01-01", "2001-01-03", "2001-01-03"], tz=tz
|
||||
)
|
||||
for res in [index.repeat(2), np.repeat(index, 2)]:
|
||||
tm.assert_index_equal(res, exp)
|
||||
assert res.freq is None
|
||||
|
||||
index = DatetimeIndex(["2001-01-01", "NaT", "2003-01-01"], tz=tz)
|
||||
exp = DatetimeIndex(
|
||||
[
|
||||
"2001-01-01",
|
||||
"2001-01-01",
|
||||
"2001-01-01",
|
||||
"NaT",
|
||||
"NaT",
|
||||
"NaT",
|
||||
"2003-01-01",
|
||||
"2003-01-01",
|
||||
"2003-01-01",
|
||||
],
|
||||
tz=tz,
|
||||
)
|
||||
for res in [index.repeat(3), np.repeat(index, 3)]:
|
||||
tm.assert_index_equal(res, exp)
|
||||
assert res.freq is None
|
||||
|
||||
def test_repeat(self, tz_naive_fixture):
|
||||
tz = tz_naive_fixture
|
||||
reps = 2
|
||||
msg = "the 'axis' parameter is not supported"
|
||||
|
||||
rng = date_range(start="2016-01-01", periods=2, freq="30Min", tz=tz)
|
||||
|
||||
expected_rng = DatetimeIndex(
|
||||
[
|
||||
Timestamp("2016-01-01 00:00:00", tz=tz),
|
||||
Timestamp("2016-01-01 00:00:00", tz=tz),
|
||||
Timestamp("2016-01-01 00:30:00", tz=tz),
|
||||
Timestamp("2016-01-01 00:30:00", tz=tz),
|
||||
]
|
||||
)
|
||||
|
||||
res = rng.repeat(reps)
|
||||
tm.assert_index_equal(res, expected_rng)
|
||||
assert res.freq is None
|
||||
|
||||
tm.assert_index_equal(np.repeat(rng, reps), expected_rng)
|
||||
with pytest.raises(ValueError, match=msg):
|
||||
np.repeat(rng, reps, axis=1)
|
@ -0,0 +1,163 @@
|
||||
from datetime import datetime
|
||||
|
||||
import pytest
|
||||
import pytz
|
||||
|
||||
from pandas.errors import NullFrequencyError
|
||||
|
||||
import pandas as pd
|
||||
from pandas import (
|
||||
DatetimeIndex,
|
||||
Series,
|
||||
date_range,
|
||||
)
|
||||
import pandas._testing as tm
|
||||
|
||||
START, END = datetime(2009, 1, 1), datetime(2010, 1, 1)
|
||||
|
||||
|
||||
class TestDatetimeIndexShift:
|
||||
|
||||
# -------------------------------------------------------------
|
||||
# DatetimeIndex.shift is used in integer addition
|
||||
|
||||
def test_dti_shift_tzaware(self, tz_naive_fixture):
|
||||
# GH#9903
|
||||
tz = tz_naive_fixture
|
||||
idx = DatetimeIndex([], name="xxx", tz=tz)
|
||||
tm.assert_index_equal(idx.shift(0, freq="H"), idx)
|
||||
tm.assert_index_equal(idx.shift(3, freq="H"), idx)
|
||||
|
||||
idx = DatetimeIndex(
|
||||
["2011-01-01 10:00", "2011-01-01 11:00", "2011-01-01 12:00"],
|
||||
name="xxx",
|
||||
tz=tz,
|
||||
freq="H",
|
||||
)
|
||||
tm.assert_index_equal(idx.shift(0, freq="H"), idx)
|
||||
exp = DatetimeIndex(
|
||||
["2011-01-01 13:00", "2011-01-01 14:00", "2011-01-01 15:00"],
|
||||
name="xxx",
|
||||
tz=tz,
|
||||
freq="H",
|
||||
)
|
||||
tm.assert_index_equal(idx.shift(3, freq="H"), exp)
|
||||
exp = DatetimeIndex(
|
||||
["2011-01-01 07:00", "2011-01-01 08:00", "2011-01-01 09:00"],
|
||||
name="xxx",
|
||||
tz=tz,
|
||||
freq="H",
|
||||
)
|
||||
tm.assert_index_equal(idx.shift(-3, freq="H"), exp)
|
||||
|
||||
def test_dti_shift_freqs(self):
|
||||
# test shift for DatetimeIndex and non DatetimeIndex
|
||||
# GH#8083
|
||||
drange = date_range("20130101", periods=5)
|
||||
result = drange.shift(1)
|
||||
expected = DatetimeIndex(
|
||||
["2013-01-02", "2013-01-03", "2013-01-04", "2013-01-05", "2013-01-06"],
|
||||
freq="D",
|
||||
)
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
result = drange.shift(-1)
|
||||
expected = DatetimeIndex(
|
||||
["2012-12-31", "2013-01-01", "2013-01-02", "2013-01-03", "2013-01-04"],
|
||||
freq="D",
|
||||
)
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
result = drange.shift(3, freq="2D")
|
||||
expected = DatetimeIndex(
|
||||
["2013-01-07", "2013-01-08", "2013-01-09", "2013-01-10", "2013-01-11"],
|
||||
freq="D",
|
||||
)
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
def test_dti_shift_int(self):
|
||||
rng = date_range("1/1/2000", periods=20)
|
||||
|
||||
result = rng + 5 * rng.freq
|
||||
expected = rng.shift(5)
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
result = rng - 5 * rng.freq
|
||||
expected = rng.shift(-5)
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
def test_dti_shift_no_freq(self):
|
||||
# GH#19147
|
||||
dti = DatetimeIndex(["2011-01-01 10:00", "2011-01-01"], freq=None)
|
||||
with pytest.raises(NullFrequencyError, match="Cannot shift with no freq"):
|
||||
dti.shift(2)
|
||||
|
||||
@pytest.mark.parametrize("tzstr", ["US/Eastern", "dateutil/US/Eastern"])
|
||||
def test_dti_shift_localized(self, tzstr):
|
||||
dr = date_range("2011/1/1", "2012/1/1", freq="W-FRI")
|
||||
dr_tz = dr.tz_localize(tzstr)
|
||||
|
||||
result = dr_tz.shift(1, "10T")
|
||||
assert result.tz == dr_tz.tz
|
||||
|
||||
def test_dti_shift_across_dst(self):
|
||||
# GH 8616
|
||||
idx = date_range("2013-11-03", tz="America/Chicago", periods=7, freq="H")
|
||||
s = Series(index=idx[:-1], dtype=object)
|
||||
result = s.shift(freq="H")
|
||||
expected = Series(index=idx[1:], dtype=object)
|
||||
tm.assert_series_equal(result, expected)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"shift, result_time",
|
||||
[
|
||||
[0, "2014-11-14 00:00:00"],
|
||||
[-1, "2014-11-13 23:00:00"],
|
||||
[1, "2014-11-14 01:00:00"],
|
||||
],
|
||||
)
|
||||
def test_dti_shift_near_midnight(self, shift, result_time):
|
||||
# GH 8616
|
||||
dt = datetime(2014, 11, 14, 0)
|
||||
dt_est = pytz.timezone("EST").localize(dt)
|
||||
s = Series(data=[1], index=[dt_est])
|
||||
result = s.shift(shift, freq="H")
|
||||
expected = Series(1, index=DatetimeIndex([result_time], tz="EST"))
|
||||
tm.assert_series_equal(result, expected)
|
||||
|
||||
def test_shift_periods(self):
|
||||
# GH#22458 : argument 'n' was deprecated in favor of 'periods'
|
||||
idx = date_range(start=START, end=END, periods=3)
|
||||
tm.assert_index_equal(idx.shift(periods=0), idx)
|
||||
tm.assert_index_equal(idx.shift(0), idx)
|
||||
|
||||
@pytest.mark.parametrize("freq", ["B", "C"])
|
||||
def test_shift_bday(self, freq):
|
||||
rng = date_range(START, END, freq=freq)
|
||||
shifted = rng.shift(5)
|
||||
assert shifted[0] == rng[5]
|
||||
assert shifted.freq == rng.freq
|
||||
|
||||
shifted = rng.shift(-5)
|
||||
assert shifted[5] == rng[0]
|
||||
assert shifted.freq == rng.freq
|
||||
|
||||
shifted = rng.shift(0)
|
||||
assert shifted[0] == rng[0]
|
||||
assert shifted.freq == rng.freq
|
||||
|
||||
def test_shift_bmonth(self):
|
||||
rng = date_range(START, END, freq=pd.offsets.BMonthEnd())
|
||||
shifted = rng.shift(1, freq=pd.offsets.BDay())
|
||||
assert shifted[0] == rng[0] + pd.offsets.BDay()
|
||||
|
||||
rng = date_range(START, END, freq=pd.offsets.BMonthEnd())
|
||||
with tm.assert_produces_warning(pd.errors.PerformanceWarning):
|
||||
shifted = rng.shift(1, freq=pd.offsets.CDay())
|
||||
assert shifted[0] == rng[0] + pd.offsets.CDay()
|
||||
|
||||
def test_shift_empty(self):
|
||||
# GH#14811
|
||||
dti = date_range(start="2016-10-21", end="2016-10-21", freq="BM")
|
||||
result = dti.shift(1)
|
||||
tm.assert_index_equal(result, dti)
|
@ -0,0 +1,44 @@
|
||||
import pytest
|
||||
|
||||
from pandas import (
|
||||
DatetimeIndex,
|
||||
date_range,
|
||||
)
|
||||
import pandas._testing as tm
|
||||
|
||||
|
||||
@pytest.mark.filterwarnings("ignore::DeprecationWarning")
|
||||
@pytest.mark.parametrize("tz", [None, "Asia/Shanghai", "Europe/Berlin"])
|
||||
@pytest.mark.parametrize("name", [None, "my_dti"])
|
||||
def test_dti_snap(name, tz):
|
||||
dti = DatetimeIndex(
|
||||
[
|
||||
"1/1/2002",
|
||||
"1/2/2002",
|
||||
"1/3/2002",
|
||||
"1/4/2002",
|
||||
"1/5/2002",
|
||||
"1/6/2002",
|
||||
"1/7/2002",
|
||||
],
|
||||
name=name,
|
||||
tz=tz,
|
||||
freq="D",
|
||||
)
|
||||
|
||||
result = dti.snap(freq="W-MON")
|
||||
expected = date_range("12/31/2001", "1/7/2002", name=name, tz=tz, freq="w-mon")
|
||||
expected = expected.repeat([3, 4])
|
||||
tm.assert_index_equal(result, expected)
|
||||
assert result.tz == expected.tz
|
||||
assert result.freq is None
|
||||
assert expected.freq is None
|
||||
|
||||
result = dti.snap(freq="B")
|
||||
|
||||
expected = date_range("1/1/2002", "1/7/2002", name=name, tz=tz, freq="b")
|
||||
expected = expected.repeat([1, 1, 1, 2, 2])
|
||||
tm.assert_index_equal(result, expected)
|
||||
assert result.tz == expected.tz
|
||||
assert result.freq is None
|
||||
assert expected.freq is None
|
@ -0,0 +1,31 @@
|
||||
from pandas import (
|
||||
DataFrame,
|
||||
Index,
|
||||
date_range,
|
||||
)
|
||||
import pandas._testing as tm
|
||||
|
||||
|
||||
class TestToFrame:
|
||||
def test_to_frame_datetime_tz(self):
|
||||
# GH#25809
|
||||
idx = date_range(start="2019-01-01", end="2019-01-30", freq="D", tz="UTC")
|
||||
result = idx.to_frame()
|
||||
expected = DataFrame(idx, index=idx)
|
||||
tm.assert_frame_equal(result, expected)
|
||||
|
||||
def test_to_frame_respects_none_name(self):
|
||||
# GH#44212 if we explicitly pass name=None, then that should be respected,
|
||||
# not changed to 0
|
||||
# GH-45448 this is first deprecated to only change in the future
|
||||
idx = date_range(start="2019-01-01", end="2019-01-30", freq="D", tz="UTC")
|
||||
with tm.assert_produces_warning(FutureWarning):
|
||||
result = idx.to_frame(name=None)
|
||||
# exp_idx = Index([None], dtype=object)
|
||||
exp_idx = Index([0])
|
||||
tm.assert_index_equal(exp_idx, result.columns)
|
||||
|
||||
with tm.assert_produces_warning(FutureWarning):
|
||||
result = idx.rename("foo").to_frame(name=None)
|
||||
exp_idx = Index(["foo"], dtype=object)
|
||||
tm.assert_index_equal(exp_idx, result.columns)
|
@ -0,0 +1,191 @@
|
||||
import warnings
|
||||
|
||||
import dateutil.tz
|
||||
from dateutil.tz import tzlocal
|
||||
import pytest
|
||||
import pytz
|
||||
|
||||
from pandas._libs.tslibs.ccalendar import MONTHS
|
||||
from pandas._libs.tslibs.period import INVALID_FREQ_ERR_MSG
|
||||
|
||||
from pandas import (
|
||||
DatetimeIndex,
|
||||
Period,
|
||||
PeriodIndex,
|
||||
Timestamp,
|
||||
date_range,
|
||||
period_range,
|
||||
)
|
||||
import pandas._testing as tm
|
||||
|
||||
|
||||
class TestToPeriod:
|
||||
def test_dti_to_period(self):
|
||||
dti = date_range(start="1/1/2005", end="12/1/2005", freq="M")
|
||||
pi1 = dti.to_period()
|
||||
pi2 = dti.to_period(freq="D")
|
||||
pi3 = dti.to_period(freq="3D")
|
||||
|
||||
assert pi1[0] == Period("Jan 2005", freq="M")
|
||||
assert pi2[0] == Period("1/31/2005", freq="D")
|
||||
assert pi3[0] == Period("1/31/2005", freq="3D")
|
||||
|
||||
assert pi1[-1] == Period("Nov 2005", freq="M")
|
||||
assert pi2[-1] == Period("11/30/2005", freq="D")
|
||||
assert pi3[-1], Period("11/30/2005", freq="3D")
|
||||
|
||||
tm.assert_index_equal(pi1, period_range("1/1/2005", "11/1/2005", freq="M"))
|
||||
tm.assert_index_equal(
|
||||
pi2, period_range("1/1/2005", "11/1/2005", freq="M").asfreq("D")
|
||||
)
|
||||
tm.assert_index_equal(
|
||||
pi3, period_range("1/1/2005", "11/1/2005", freq="M").asfreq("3D")
|
||||
)
|
||||
|
||||
@pytest.mark.parametrize("month", MONTHS)
|
||||
def test_to_period_quarterly(self, month):
|
||||
# make sure we can make the round trip
|
||||
freq = f"Q-{month}"
|
||||
rng = period_range("1989Q3", "1991Q3", freq=freq)
|
||||
stamps = rng.to_timestamp()
|
||||
result = stamps.to_period(freq)
|
||||
tm.assert_index_equal(rng, result)
|
||||
|
||||
@pytest.mark.parametrize("off", ["BQ", "QS", "BQS"])
|
||||
def test_to_period_quarterlyish(self, off):
|
||||
rng = date_range("01-Jan-2012", periods=8, freq=off)
|
||||
prng = rng.to_period()
|
||||
assert prng.freq == "Q-DEC"
|
||||
|
||||
@pytest.mark.parametrize("off", ["BA", "AS", "BAS"])
|
||||
def test_to_period_annualish(self, off):
|
||||
rng = date_range("01-Jan-2012", periods=8, freq=off)
|
||||
prng = rng.to_period()
|
||||
assert prng.freq == "A-DEC"
|
||||
|
||||
def test_to_period_monthish(self):
|
||||
offsets = ["MS", "BM"]
|
||||
for off in offsets:
|
||||
rng = date_range("01-Jan-2012", periods=8, freq=off)
|
||||
prng = rng.to_period()
|
||||
assert prng.freq == "M"
|
||||
|
||||
rng = date_range("01-Jan-2012", periods=8, freq="M")
|
||||
prng = rng.to_period()
|
||||
assert prng.freq == "M"
|
||||
|
||||
with pytest.raises(ValueError, match=INVALID_FREQ_ERR_MSG):
|
||||
date_range("01-Jan-2012", periods=8, freq="EOM")
|
||||
|
||||
def test_to_period_infer(self):
|
||||
# https://github.com/pandas-dev/pandas/issues/33358
|
||||
rng = date_range(
|
||||
start="2019-12-22 06:40:00+00:00",
|
||||
end="2019-12-22 08:45:00+00:00",
|
||||
freq="5min",
|
||||
)
|
||||
|
||||
with tm.assert_produces_warning(None):
|
||||
# Using simple filter because we are not checking for the warning here
|
||||
warnings.simplefilter("ignore", UserWarning)
|
||||
|
||||
pi1 = rng.to_period("5min")
|
||||
|
||||
with tm.assert_produces_warning(None):
|
||||
# Using simple filter because we are not checking for the warning here
|
||||
warnings.simplefilter("ignore", UserWarning)
|
||||
|
||||
pi2 = rng.to_period()
|
||||
|
||||
tm.assert_index_equal(pi1, pi2)
|
||||
|
||||
def test_period_dt64_round_trip(self):
|
||||
dti = date_range("1/1/2000", "1/7/2002", freq="B")
|
||||
pi = dti.to_period()
|
||||
tm.assert_index_equal(pi.to_timestamp(), dti)
|
||||
|
||||
dti = date_range("1/1/2000", "1/7/2002", freq="B")
|
||||
pi = dti.to_period(freq="H")
|
||||
tm.assert_index_equal(pi.to_timestamp(), dti)
|
||||
|
||||
def test_to_period_millisecond(self):
|
||||
index = DatetimeIndex(
|
||||
[
|
||||
Timestamp("2007-01-01 10:11:12.123456Z"),
|
||||
Timestamp("2007-01-01 10:11:13.789123Z"),
|
||||
]
|
||||
)
|
||||
|
||||
with tm.assert_produces_warning(UserWarning):
|
||||
# warning that timezone info will be lost
|
||||
period = index.to_period(freq="L")
|
||||
assert 2 == len(period)
|
||||
assert period[0] == Period("2007-01-01 10:11:12.123Z", "L")
|
||||
assert period[1] == Period("2007-01-01 10:11:13.789Z", "L")
|
||||
|
||||
def test_to_period_microsecond(self):
|
||||
index = DatetimeIndex(
|
||||
[
|
||||
Timestamp("2007-01-01 10:11:12.123456Z"),
|
||||
Timestamp("2007-01-01 10:11:13.789123Z"),
|
||||
]
|
||||
)
|
||||
|
||||
with tm.assert_produces_warning(UserWarning):
|
||||
# warning that timezone info will be lost
|
||||
period = index.to_period(freq="U")
|
||||
assert 2 == len(period)
|
||||
assert period[0] == Period("2007-01-01 10:11:12.123456Z", "U")
|
||||
assert period[1] == Period("2007-01-01 10:11:13.789123Z", "U")
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"tz",
|
||||
["US/Eastern", pytz.utc, tzlocal(), "dateutil/US/Eastern", dateutil.tz.tzutc()],
|
||||
)
|
||||
def test_to_period_tz(self, tz):
|
||||
ts = date_range("1/1/2000", "2/1/2000", tz=tz)
|
||||
|
||||
with tm.assert_produces_warning(UserWarning):
|
||||
# GH#21333 warning that timezone info will be lost
|
||||
# filter warning about freq deprecation
|
||||
warnings.filterwarnings("ignore", category=FutureWarning)
|
||||
|
||||
result = ts.to_period()[0]
|
||||
expected = ts[0].to_period()
|
||||
|
||||
assert result == expected
|
||||
|
||||
expected = date_range("1/1/2000", "2/1/2000").to_period()
|
||||
|
||||
with tm.assert_produces_warning(UserWarning):
|
||||
# GH#21333 warning that timezone info will be lost
|
||||
result = ts.to_period()
|
||||
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
@pytest.mark.parametrize("tz", ["Etc/GMT-1", "Etc/GMT+1"])
|
||||
def test_to_period_tz_utc_offset_consistency(self, tz):
|
||||
# GH#22905
|
||||
ts = date_range("1/1/2000", "2/1/2000", tz="Etc/GMT-1")
|
||||
with tm.assert_produces_warning(UserWarning):
|
||||
warnings.filterwarnings("ignore", category=FutureWarning)
|
||||
|
||||
result = ts.to_period()[0]
|
||||
expected = ts[0].to_period()
|
||||
assert result == expected
|
||||
|
||||
def test_to_period_nofreq(self):
|
||||
idx = DatetimeIndex(["2000-01-01", "2000-01-02", "2000-01-04"])
|
||||
msg = "You must pass a freq argument as current index has none."
|
||||
with pytest.raises(ValueError, match=msg):
|
||||
idx.to_period()
|
||||
|
||||
idx = DatetimeIndex(["2000-01-01", "2000-01-02", "2000-01-03"], freq="infer")
|
||||
assert idx.freqstr == "D"
|
||||
expected = PeriodIndex(["2000-01-01", "2000-01-02", "2000-01-03"], freq="D")
|
||||
tm.assert_index_equal(idx.to_period(), expected)
|
||||
|
||||
# GH#7606
|
||||
idx = DatetimeIndex(["2000-01-01", "2000-01-02", "2000-01-03"])
|
||||
assert idx.freqstr is None
|
||||
tm.assert_index_equal(idx.to_period(), expected)
|
@ -0,0 +1,40 @@
|
||||
import numpy as np
|
||||
import pytest
|
||||
|
||||
from pandas import (
|
||||
DatetimeIndex,
|
||||
Series,
|
||||
)
|
||||
import pandas._testing as tm
|
||||
|
||||
|
||||
class TestToSeries:
|
||||
@pytest.fixture
|
||||
def idx_expected(self):
|
||||
naive = DatetimeIndex(["2013-1-1 13:00", "2013-1-2 14:00"], name="B")
|
||||
idx = naive.tz_localize("US/Pacific")
|
||||
|
||||
expected = Series(np.array(idx.tolist(), dtype="object"), name="B")
|
||||
|
||||
assert expected.dtype == idx.dtype
|
||||
return idx, expected
|
||||
|
||||
def test_to_series_keep_tz_deprecated_true(self, idx_expected):
|
||||
# convert to series while keeping the timezone
|
||||
idx, expected = idx_expected
|
||||
|
||||
msg = "stop passing 'keep_tz'"
|
||||
with tm.assert_produces_warning(FutureWarning) as m:
|
||||
result = idx.to_series(keep_tz=True, index=[0, 1])
|
||||
assert msg in str(m[0].message)
|
||||
|
||||
tm.assert_series_equal(result, expected)
|
||||
|
||||
def test_to_series_keep_tz_deprecated_false(self, idx_expected):
|
||||
idx, expected = idx_expected
|
||||
|
||||
with tm.assert_produces_warning(FutureWarning) as m:
|
||||
result = idx.to_series(keep_tz=False, index=[0, 1])
|
||||
tm.assert_series_equal(result, expected.dt.tz_convert(None))
|
||||
msg = "do 'idx.tz_convert(None)' before calling"
|
||||
assert msg in str(m[0].message)
|
@ -0,0 +1,31 @@
|
||||
from datetime import timedelta
|
||||
|
||||
from pandas import (
|
||||
Index,
|
||||
Timestamp,
|
||||
date_range,
|
||||
isna,
|
||||
)
|
||||
import pandas._testing as tm
|
||||
|
||||
|
||||
class TestAsOf:
|
||||
def test_asof_partial(self):
|
||||
index = date_range("2010-01-01", periods=2, freq="m")
|
||||
expected = Timestamp("2010-02-28")
|
||||
result = index.asof("2010-02")
|
||||
assert result == expected
|
||||
assert not isinstance(result, Index)
|
||||
|
||||
def test_asof(self):
|
||||
index = tm.makeDateIndex(100)
|
||||
|
||||
dt = index[0]
|
||||
assert index.asof(dt) == dt
|
||||
assert isna(index.asof(dt - timedelta(1)))
|
||||
|
||||
dt = index[-1]
|
||||
assert index.asof(dt + timedelta(1)) == dt
|
||||
|
||||
dt = index[0].to_pydatetime()
|
||||
assert isinstance(index.asof(dt), Timestamp)
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,168 @@
|
||||
from datetime import date
|
||||
|
||||
import dateutil
|
||||
import numpy as np
|
||||
import pytest
|
||||
|
||||
import pandas as pd
|
||||
from pandas import (
|
||||
DataFrame,
|
||||
DatetimeIndex,
|
||||
Index,
|
||||
Timestamp,
|
||||
date_range,
|
||||
offsets,
|
||||
)
|
||||
import pandas._testing as tm
|
||||
|
||||
|
||||
class TestDatetimeIndex:
|
||||
def test_time_overflow_for_32bit_machines(self):
|
||||
# GH8943. On some machines NumPy defaults to np.int32 (for example,
|
||||
# 32-bit Linux machines). In the function _generate_regular_range
|
||||
# found in tseries/index.py, `periods` gets multiplied by `strides`
|
||||
# (which has value 1e9) and since the max value for np.int32 is ~2e9,
|
||||
# and since those machines won't promote np.int32 to np.int64, we get
|
||||
# overflow.
|
||||
periods = np.int_(1000)
|
||||
|
||||
idx1 = date_range(start="2000", periods=periods, freq="S")
|
||||
assert len(idx1) == periods
|
||||
|
||||
idx2 = date_range(end="2000", periods=periods, freq="S")
|
||||
assert len(idx2) == periods
|
||||
|
||||
def test_nat(self):
|
||||
assert DatetimeIndex([np.nan])[0] is pd.NaT
|
||||
|
||||
def test_week_of_month_frequency(self):
|
||||
# GH 5348: "ValueError: Could not evaluate WOM-1SUN" shouldn't raise
|
||||
d1 = date(2002, 9, 1)
|
||||
d2 = date(2013, 10, 27)
|
||||
d3 = date(2012, 9, 30)
|
||||
idx1 = DatetimeIndex([d1, d2])
|
||||
idx2 = DatetimeIndex([d3])
|
||||
result_append = idx1.append(idx2)
|
||||
expected = DatetimeIndex([d1, d2, d3])
|
||||
tm.assert_index_equal(result_append, expected)
|
||||
result_union = idx1.union(idx2)
|
||||
expected = DatetimeIndex([d1, d3, d2])
|
||||
tm.assert_index_equal(result_union, expected)
|
||||
|
||||
# GH 5115
|
||||
result = date_range("2013-1-1", periods=4, freq="WOM-1SAT")
|
||||
dates = ["2013-01-05", "2013-02-02", "2013-03-02", "2013-04-06"]
|
||||
expected = DatetimeIndex(dates, freq="WOM-1SAT")
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
def test_append_nondatetimeindex(self):
|
||||
rng = date_range("1/1/2000", periods=10)
|
||||
idx = Index(["a", "b", "c", "d"])
|
||||
|
||||
result = rng.append(idx)
|
||||
assert isinstance(result[0], Timestamp)
|
||||
|
||||
def test_iteration_preserves_tz(self):
|
||||
# see gh-8890
|
||||
index = date_range("2012-01-01", periods=3, freq="H", tz="US/Eastern")
|
||||
|
||||
for i, ts in enumerate(index):
|
||||
result = ts
|
||||
expected = index[i]
|
||||
assert result == expected
|
||||
|
||||
index = date_range(
|
||||
"2012-01-01", periods=3, freq="H", tz=dateutil.tz.tzoffset(None, -28800)
|
||||
)
|
||||
|
||||
for i, ts in enumerate(index):
|
||||
result = ts
|
||||
expected = index[i]
|
||||
assert result._repr_base == expected._repr_base
|
||||
assert result == expected
|
||||
|
||||
# 9100
|
||||
index = DatetimeIndex(
|
||||
["2014-12-01 03:32:39.987000-08:00", "2014-12-01 04:12:34.987000-08:00"]
|
||||
)
|
||||
for i, ts in enumerate(index):
|
||||
result = ts
|
||||
expected = index[i]
|
||||
assert result._repr_base == expected._repr_base
|
||||
assert result == expected
|
||||
|
||||
@pytest.mark.parametrize("periods", [0, 9999, 10000, 10001])
|
||||
def test_iteration_over_chunksize(self, periods):
|
||||
# GH21012
|
||||
|
||||
index = date_range("2000-01-01 00:00:00", periods=periods, freq="min")
|
||||
num = 0
|
||||
for stamp in index:
|
||||
assert index[num] == stamp
|
||||
num += 1
|
||||
assert num == len(index)
|
||||
|
||||
def test_misc_coverage(self):
|
||||
rng = date_range("1/1/2000", periods=5)
|
||||
result = rng.groupby(rng.day)
|
||||
assert isinstance(list(result.values())[0][0], Timestamp)
|
||||
|
||||
def test_groupby_function_tuple_1677(self):
|
||||
df = DataFrame(np.random.rand(100), index=date_range("1/1/2000", periods=100))
|
||||
monthly_group = df.groupby(lambda x: (x.year, x.month))
|
||||
|
||||
result = monthly_group.mean()
|
||||
assert isinstance(result.index[0], tuple)
|
||||
|
||||
def assert_index_parameters(self, index):
|
||||
assert index.freq == "40960N"
|
||||
assert index.inferred_freq == "40960N"
|
||||
|
||||
def test_ns_index(self):
|
||||
nsamples = 400
|
||||
ns = int(1e9 / 24414)
|
||||
dtstart = np.datetime64("2012-09-20T00:00:00")
|
||||
|
||||
dt = dtstart + np.arange(nsamples) * np.timedelta64(ns, "ns")
|
||||
freq = ns * offsets.Nano()
|
||||
index = DatetimeIndex(dt, freq=freq, name="time")
|
||||
self.assert_index_parameters(index)
|
||||
|
||||
new_index = date_range(start=index[0], end=index[-1], freq=index.freq)
|
||||
self.assert_index_parameters(new_index)
|
||||
|
||||
def test_asarray_tz_naive(self):
|
||||
# This shouldn't produce a warning.
|
||||
idx = date_range("2000", periods=2)
|
||||
# M8[ns] by default
|
||||
result = np.asarray(idx)
|
||||
|
||||
expected = np.array(["2000-01-01", "2000-01-02"], dtype="M8[ns]")
|
||||
tm.assert_numpy_array_equal(result, expected)
|
||||
|
||||
# optionally, object
|
||||
result = np.asarray(idx, dtype=object)
|
||||
|
||||
expected = np.array([Timestamp("2000-01-01"), Timestamp("2000-01-02")])
|
||||
tm.assert_numpy_array_equal(result, expected)
|
||||
|
||||
def test_asarray_tz_aware(self):
|
||||
tz = "US/Central"
|
||||
idx = date_range("2000", periods=2, tz=tz)
|
||||
expected = np.array(["2000-01-01T06", "2000-01-02T06"], dtype="M8[ns]")
|
||||
result = np.asarray(idx, dtype="datetime64[ns]")
|
||||
|
||||
tm.assert_numpy_array_equal(result, expected)
|
||||
|
||||
# Old behavior with no warning
|
||||
result = np.asarray(idx, dtype="M8[ns]")
|
||||
|
||||
tm.assert_numpy_array_equal(result, expected)
|
||||
|
||||
# Future behavior with no warning
|
||||
expected = np.array(
|
||||
[Timestamp("2000-01-01", tz=tz), Timestamp("2000-01-02", tz=tz)]
|
||||
)
|
||||
result = np.asarray(idx, dtype=object)
|
||||
|
||||
tm.assert_numpy_array_equal(result, expected)
|
@ -0,0 +1,39 @@
|
||||
""" generic tests from the Datetimelike class """
|
||||
import pytest
|
||||
|
||||
from pandas import (
|
||||
DatetimeIndex,
|
||||
date_range,
|
||||
)
|
||||
import pandas._testing as tm
|
||||
from pandas.tests.indexes.datetimelike import DatetimeLike
|
||||
|
||||
|
||||
class TestDatetimeIndex(DatetimeLike):
|
||||
_index_cls = DatetimeIndex
|
||||
|
||||
@pytest.fixture
|
||||
def simple_index(self) -> DatetimeIndex:
|
||||
return date_range("20130101", periods=5)
|
||||
|
||||
@pytest.fixture(
|
||||
params=[tm.makeDateIndex(10), date_range("20130110", periods=10, freq="-1D")],
|
||||
ids=["index_inc", "index_dec"],
|
||||
)
|
||||
def index(self, request):
|
||||
return request.param
|
||||
|
||||
def test_format(self, simple_index):
|
||||
# GH35439
|
||||
idx = simple_index
|
||||
expected = [f"{x:%Y-%m-%d}" for x in idx]
|
||||
assert idx.format() == expected
|
||||
|
||||
def test_shift(self):
|
||||
pass # handled in test_ops
|
||||
|
||||
def test_intersection(self):
|
||||
pass # handled in test_setops
|
||||
|
||||
def test_union(self):
|
||||
pass # handled in test_setops
|
@ -0,0 +1,138 @@
|
||||
import pytest
|
||||
|
||||
from pandas import (
|
||||
DatetimeIndex,
|
||||
Series,
|
||||
date_range,
|
||||
)
|
||||
import pandas._testing as tm
|
||||
|
||||
|
||||
class TestDelete:
|
||||
def test_delete(self):
|
||||
idx = date_range(start="2000-01-01", periods=5, freq="M", name="idx")
|
||||
|
||||
# preserve freq
|
||||
expected_0 = date_range(start="2000-02-01", periods=4, freq="M", name="idx")
|
||||
expected_4 = date_range(start="2000-01-01", periods=4, freq="M", name="idx")
|
||||
|
||||
# reset freq to None
|
||||
expected_1 = DatetimeIndex(
|
||||
["2000-01-31", "2000-03-31", "2000-04-30", "2000-05-31"],
|
||||
freq=None,
|
||||
name="idx",
|
||||
)
|
||||
|
||||
cases = {
|
||||
0: expected_0,
|
||||
-5: expected_0,
|
||||
-1: expected_4,
|
||||
4: expected_4,
|
||||
1: expected_1,
|
||||
}
|
||||
for n, expected in cases.items():
|
||||
result = idx.delete(n)
|
||||
tm.assert_index_equal(result, expected)
|
||||
assert result.name == expected.name
|
||||
assert result.freq == expected.freq
|
||||
|
||||
with pytest.raises((IndexError, ValueError), match="out of bounds"):
|
||||
# either depending on numpy version
|
||||
idx.delete(5)
|
||||
|
||||
for tz in [None, "Asia/Tokyo", "US/Pacific"]:
|
||||
idx = date_range(
|
||||
start="2000-01-01 09:00", periods=10, freq="H", name="idx", tz=tz
|
||||
)
|
||||
|
||||
expected = date_range(
|
||||
start="2000-01-01 10:00", periods=9, freq="H", name="idx", tz=tz
|
||||
)
|
||||
result = idx.delete(0)
|
||||
tm.assert_index_equal(result, expected)
|
||||
assert result.name == expected.name
|
||||
assert result.freqstr == "H"
|
||||
assert result.tz == expected.tz
|
||||
|
||||
expected = date_range(
|
||||
start="2000-01-01 09:00", periods=9, freq="H", name="idx", tz=tz
|
||||
)
|
||||
result = idx.delete(-1)
|
||||
tm.assert_index_equal(result, expected)
|
||||
assert result.name == expected.name
|
||||
assert result.freqstr == "H"
|
||||
assert result.tz == expected.tz
|
||||
|
||||
def test_delete_slice(self):
|
||||
idx = date_range(start="2000-01-01", periods=10, freq="D", name="idx")
|
||||
|
||||
# preserve freq
|
||||
expected_0_2 = date_range(start="2000-01-04", periods=7, freq="D", name="idx")
|
||||
expected_7_9 = date_range(start="2000-01-01", periods=7, freq="D", name="idx")
|
||||
|
||||
# reset freq to None
|
||||
expected_3_5 = DatetimeIndex(
|
||||
[
|
||||
"2000-01-01",
|
||||
"2000-01-02",
|
||||
"2000-01-03",
|
||||
"2000-01-07",
|
||||
"2000-01-08",
|
||||
"2000-01-09",
|
||||
"2000-01-10",
|
||||
],
|
||||
freq=None,
|
||||
name="idx",
|
||||
)
|
||||
|
||||
cases = {
|
||||
(0, 1, 2): expected_0_2,
|
||||
(7, 8, 9): expected_7_9,
|
||||
(3, 4, 5): expected_3_5,
|
||||
}
|
||||
for n, expected in cases.items():
|
||||
result = idx.delete(n)
|
||||
tm.assert_index_equal(result, expected)
|
||||
assert result.name == expected.name
|
||||
assert result.freq == expected.freq
|
||||
|
||||
result = idx.delete(slice(n[0], n[-1] + 1))
|
||||
tm.assert_index_equal(result, expected)
|
||||
assert result.name == expected.name
|
||||
assert result.freq == expected.freq
|
||||
|
||||
for tz in [None, "Asia/Tokyo", "US/Pacific"]:
|
||||
ts = Series(
|
||||
1,
|
||||
index=date_range(
|
||||
"2000-01-01 09:00", periods=10, freq="H", name="idx", tz=tz
|
||||
),
|
||||
)
|
||||
# preserve freq
|
||||
result = ts.drop(ts.index[:5]).index
|
||||
expected = date_range(
|
||||
"2000-01-01 14:00", periods=5, freq="H", name="idx", tz=tz
|
||||
)
|
||||
tm.assert_index_equal(result, expected)
|
||||
assert result.name == expected.name
|
||||
assert result.freq == expected.freq
|
||||
assert result.tz == expected.tz
|
||||
|
||||
# reset freq to None
|
||||
result = ts.drop(ts.index[[1, 3, 5, 7, 9]]).index
|
||||
expected = DatetimeIndex(
|
||||
[
|
||||
"2000-01-01 09:00",
|
||||
"2000-01-01 11:00",
|
||||
"2000-01-01 13:00",
|
||||
"2000-01-01 15:00",
|
||||
"2000-01-01 17:00",
|
||||
],
|
||||
freq=None,
|
||||
name="idx",
|
||||
tz=tz,
|
||||
)
|
||||
tm.assert_index_equal(result, expected)
|
||||
assert result.name == expected.name
|
||||
assert result.freq == expected.freq
|
||||
assert result.tz == expected.tz
|
@ -0,0 +1,273 @@
|
||||
from datetime import datetime
|
||||
|
||||
import dateutil.tz
|
||||
import numpy as np
|
||||
import pytest
|
||||
import pytz
|
||||
|
||||
import pandas as pd
|
||||
from pandas import (
|
||||
DatetimeIndex,
|
||||
Series,
|
||||
)
|
||||
import pandas._testing as tm
|
||||
|
||||
|
||||
def test_to_native_types_method_deprecated():
|
||||
index = pd.date_range(freq="1D", periods=3, start="2017-01-01")
|
||||
expected = np.array(["2017-01-01", "2017-01-02", "2017-01-03"], dtype=object)
|
||||
|
||||
with tm.assert_produces_warning(FutureWarning):
|
||||
result = index.to_native_types()
|
||||
|
||||
tm.assert_numpy_array_equal(result, expected)
|
||||
|
||||
# Make sure slicing works
|
||||
expected = np.array(["2017-01-01", "2017-01-03"], dtype=object)
|
||||
|
||||
with tm.assert_produces_warning(FutureWarning):
|
||||
result = index.to_native_types([0, 2])
|
||||
|
||||
tm.assert_numpy_array_equal(result, expected)
|
||||
|
||||
|
||||
def test_to_native_types():
|
||||
index = pd.date_range(freq="1D", periods=3, start="2017-01-01")
|
||||
|
||||
# First, with no arguments.
|
||||
expected = np.array(["2017-01-01", "2017-01-02", "2017-01-03"], dtype=object)
|
||||
|
||||
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=object)
|
||||
|
||||
result = index._format_native_types(date_format="%m-%Y-%d")
|
||||
tm.assert_numpy_array_equal(result, expected)
|
||||
|
||||
# NULL object handling should work
|
||||
index = DatetimeIndex(["2017-01-01", pd.NaT, "2017-01-03"])
|
||||
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 TestDatetimeIndexRendering:
|
||||
def test_dti_repr_short(self):
|
||||
dr = pd.date_range(start="1/1/2012", periods=1)
|
||||
repr(dr)
|
||||
|
||||
dr = pd.date_range(start="1/1/2012", periods=2)
|
||||
repr(dr)
|
||||
|
||||
dr = pd.date_range(start="1/1/2012", periods=3)
|
||||
repr(dr)
|
||||
|
||||
@pytest.mark.parametrize("method", ["__repr__", "__str__"])
|
||||
def test_dti_representation(self, method):
|
||||
idxs = []
|
||||
idxs.append(DatetimeIndex([], freq="D"))
|
||||
idxs.append(DatetimeIndex(["2011-01-01"], freq="D"))
|
||||
idxs.append(DatetimeIndex(["2011-01-01", "2011-01-02"], freq="D"))
|
||||
idxs.append(DatetimeIndex(["2011-01-01", "2011-01-02", "2011-01-03"], freq="D"))
|
||||
idxs.append(
|
||||
DatetimeIndex(
|
||||
["2011-01-01 09:00", "2011-01-01 10:00", "2011-01-01 11:00"],
|
||||
freq="H",
|
||||
tz="Asia/Tokyo",
|
||||
)
|
||||
)
|
||||
idxs.append(
|
||||
DatetimeIndex(
|
||||
["2011-01-01 09:00", "2011-01-01 10:00", pd.NaT], tz="US/Eastern"
|
||||
)
|
||||
)
|
||||
idxs.append(
|
||||
DatetimeIndex(["2011-01-01 09:00", "2011-01-01 10:00", pd.NaT], tz="UTC")
|
||||
)
|
||||
|
||||
exp = []
|
||||
exp.append("DatetimeIndex([], dtype='datetime64[ns]', freq='D')")
|
||||
exp.append("DatetimeIndex(['2011-01-01'], dtype='datetime64[ns]', freq='D')")
|
||||
exp.append(
|
||||
"DatetimeIndex(['2011-01-01', '2011-01-02'], "
|
||||
"dtype='datetime64[ns]', freq='D')"
|
||||
)
|
||||
exp.append(
|
||||
"DatetimeIndex(['2011-01-01', '2011-01-02', '2011-01-03'], "
|
||||
"dtype='datetime64[ns]', freq='D')"
|
||||
)
|
||||
exp.append(
|
||||
"DatetimeIndex(['2011-01-01 09:00:00+09:00', "
|
||||
"'2011-01-01 10:00:00+09:00', '2011-01-01 11:00:00+09:00']"
|
||||
", dtype='datetime64[ns, Asia/Tokyo]', freq='H')"
|
||||
)
|
||||
exp.append(
|
||||
"DatetimeIndex(['2011-01-01 09:00:00-05:00', "
|
||||
"'2011-01-01 10:00:00-05:00', 'NaT'], "
|
||||
"dtype='datetime64[ns, US/Eastern]', freq=None)"
|
||||
)
|
||||
exp.append(
|
||||
"DatetimeIndex(['2011-01-01 09:00:00+00:00', "
|
||||
"'2011-01-01 10:00:00+00:00', 'NaT'], "
|
||||
"dtype='datetime64[ns, UTC]', freq=None)"
|
||||
""
|
||||
)
|
||||
|
||||
with pd.option_context("display.width", 300):
|
||||
for indx, expected in zip(idxs, exp):
|
||||
result = getattr(indx, method)()
|
||||
assert result == expected
|
||||
|
||||
def test_dti_representation_to_series(self):
|
||||
idx1 = DatetimeIndex([], freq="D")
|
||||
idx2 = DatetimeIndex(["2011-01-01"], freq="D")
|
||||
idx3 = DatetimeIndex(["2011-01-01", "2011-01-02"], freq="D")
|
||||
idx4 = DatetimeIndex(["2011-01-01", "2011-01-02", "2011-01-03"], freq="D")
|
||||
idx5 = DatetimeIndex(
|
||||
["2011-01-01 09:00", "2011-01-01 10:00", "2011-01-01 11:00"],
|
||||
freq="H",
|
||||
tz="Asia/Tokyo",
|
||||
)
|
||||
idx6 = DatetimeIndex(
|
||||
["2011-01-01 09:00", "2011-01-01 10:00", pd.NaT], tz="US/Eastern"
|
||||
)
|
||||
idx7 = DatetimeIndex(["2011-01-01 09:00", "2011-01-02 10:15"])
|
||||
|
||||
exp1 = """Series([], dtype: datetime64[ns])"""
|
||||
|
||||
exp2 = "0 2011-01-01\ndtype: datetime64[ns]"
|
||||
|
||||
exp3 = "0 2011-01-01\n1 2011-01-02\ndtype: datetime64[ns]"
|
||||
|
||||
exp4 = (
|
||||
"0 2011-01-01\n"
|
||||
"1 2011-01-02\n"
|
||||
"2 2011-01-03\n"
|
||||
"dtype: datetime64[ns]"
|
||||
)
|
||||
|
||||
exp5 = (
|
||||
"0 2011-01-01 09:00:00+09:00\n"
|
||||
"1 2011-01-01 10:00:00+09:00\n"
|
||||
"2 2011-01-01 11:00:00+09:00\n"
|
||||
"dtype: datetime64[ns, Asia/Tokyo]"
|
||||
)
|
||||
|
||||
exp6 = (
|
||||
"0 2011-01-01 09:00:00-05:00\n"
|
||||
"1 2011-01-01 10:00:00-05:00\n"
|
||||
"2 NaT\n"
|
||||
"dtype: datetime64[ns, US/Eastern]"
|
||||
)
|
||||
|
||||
exp7 = (
|
||||
"0 2011-01-01 09:00:00\n"
|
||||
"1 2011-01-02 10:15:00\n"
|
||||
"dtype: datetime64[ns]"
|
||||
)
|
||||
|
||||
with pd.option_context("display.width", 300):
|
||||
for idx, expected in zip(
|
||||
[idx1, idx2, idx3, idx4, idx5, idx6, idx7],
|
||||
[exp1, exp2, exp3, exp4, exp5, exp6, exp7],
|
||||
):
|
||||
result = repr(Series(idx))
|
||||
assert result == expected
|
||||
|
||||
def test_dti_summary(self):
|
||||
# GH#9116
|
||||
idx1 = DatetimeIndex([], freq="D")
|
||||
idx2 = DatetimeIndex(["2011-01-01"], freq="D")
|
||||
idx3 = DatetimeIndex(["2011-01-01", "2011-01-02"], freq="D")
|
||||
idx4 = DatetimeIndex(["2011-01-01", "2011-01-02", "2011-01-03"], freq="D")
|
||||
idx5 = DatetimeIndex(
|
||||
["2011-01-01 09:00", "2011-01-01 10:00", "2011-01-01 11:00"],
|
||||
freq="H",
|
||||
tz="Asia/Tokyo",
|
||||
)
|
||||
idx6 = DatetimeIndex(
|
||||
["2011-01-01 09:00", "2011-01-01 10:00", pd.NaT], tz="US/Eastern"
|
||||
)
|
||||
|
||||
exp1 = "DatetimeIndex: 0 entries\nFreq: D"
|
||||
|
||||
exp2 = "DatetimeIndex: 1 entries, 2011-01-01 to 2011-01-01\nFreq: D"
|
||||
|
||||
exp3 = "DatetimeIndex: 2 entries, 2011-01-01 to 2011-01-02\nFreq: D"
|
||||
|
||||
exp4 = "DatetimeIndex: 3 entries, 2011-01-01 to 2011-01-03\nFreq: D"
|
||||
|
||||
exp5 = (
|
||||
"DatetimeIndex: 3 entries, 2011-01-01 09:00:00+09:00 "
|
||||
"to 2011-01-01 11:00:00+09:00\n"
|
||||
"Freq: H"
|
||||
)
|
||||
|
||||
exp6 = """DatetimeIndex: 3 entries, 2011-01-01 09:00:00-05:00 to NaT"""
|
||||
|
||||
for idx, expected in zip(
|
||||
[idx1, idx2, idx3, idx4, idx5, idx6], [exp1, exp2, exp3, exp4, exp5, exp6]
|
||||
):
|
||||
result = idx._summary()
|
||||
assert result == expected
|
||||
|
||||
def test_dti_business_repr(self):
|
||||
# only really care that it works
|
||||
repr(pd.bdate_range(datetime(2009, 1, 1), datetime(2010, 1, 1)))
|
||||
|
||||
def test_dti_business_summary(self):
|
||||
rng = pd.bdate_range(datetime(2009, 1, 1), datetime(2010, 1, 1))
|
||||
rng._summary()
|
||||
rng[2:2]._summary()
|
||||
|
||||
def test_dti_business_summary_pytz(self):
|
||||
pd.bdate_range("1/1/2005", "1/1/2009", tz=pytz.utc)._summary()
|
||||
|
||||
def test_dti_business_summary_dateutil(self):
|
||||
pd.bdate_range("1/1/2005", "1/1/2009", tz=dateutil.tz.tzutc())._summary()
|
||||
|
||||
def test_dti_custom_business_repr(self):
|
||||
# only really care that it works
|
||||
repr(pd.bdate_range(datetime(2009, 1, 1), datetime(2010, 1, 1), freq="C"))
|
||||
|
||||
def test_dti_custom_business_summary(self):
|
||||
rng = pd.bdate_range(datetime(2009, 1, 1), datetime(2010, 1, 1), freq="C")
|
||||
rng._summary()
|
||||
rng[2:2]._summary()
|
||||
|
||||
def test_dti_custom_business_summary_pytz(self):
|
||||
pd.bdate_range("1/1/2005", "1/1/2009", freq="C", tz=pytz.utc)._summary()
|
||||
|
||||
def test_dti_custom_business_summary_dateutil(self):
|
||||
pd.bdate_range(
|
||||
"1/1/2005", "1/1/2009", freq="C", tz=dateutil.tz.tzutc()
|
||||
)._summary()
|
||||
|
||||
|
||||
class TestFormat:
|
||||
def test_format_with_name_time_info(self):
|
||||
# bug I fixed 12/20/2011
|
||||
dates = pd.date_range("2011-01-01 04:00:00", periods=10, name="something")
|
||||
|
||||
formatted = dates.format(name=True)
|
||||
assert formatted[0] == "something"
|
||||
|
||||
def test_format_datetime_with_time(self):
|
||||
dti = DatetimeIndex([datetime(2012, 2, 7), datetime(2012, 2, 7, 23)])
|
||||
|
||||
result = dti.format()
|
||||
expected = ["2012-02-07 00:00:00", "2012-02-07 23:00:00"]
|
||||
assert len(result) == 2
|
||||
assert result == expected
|
@ -0,0 +1,61 @@
|
||||
import pytest
|
||||
|
||||
from pandas import (
|
||||
DatetimeIndex,
|
||||
date_range,
|
||||
)
|
||||
|
||||
from pandas.tseries.offsets import (
|
||||
BDay,
|
||||
DateOffset,
|
||||
Day,
|
||||
Hour,
|
||||
)
|
||||
|
||||
|
||||
class TestFreq:
|
||||
def test_freq_setter_errors(self):
|
||||
# GH#20678
|
||||
idx = DatetimeIndex(["20180101", "20180103", "20180105"])
|
||||
|
||||
# setting with an incompatible freq
|
||||
msg = (
|
||||
"Inferred frequency 2D from passed values does not conform to "
|
||||
"passed frequency 5D"
|
||||
)
|
||||
with pytest.raises(ValueError, match=msg):
|
||||
idx._data.freq = "5D"
|
||||
|
||||
# setting with non-freq string
|
||||
with pytest.raises(ValueError, match="Invalid frequency"):
|
||||
idx._data.freq = "foo"
|
||||
|
||||
@pytest.mark.parametrize("values", [["20180101", "20180103", "20180105"], []])
|
||||
@pytest.mark.parametrize("freq", ["2D", Day(2), "2B", BDay(2), "48H", Hour(48)])
|
||||
@pytest.mark.parametrize("tz", [None, "US/Eastern"])
|
||||
def test_freq_setter(self, values, freq, tz):
|
||||
# GH#20678
|
||||
idx = DatetimeIndex(values, tz=tz)
|
||||
|
||||
# can set to an offset, converting from string if necessary
|
||||
idx._data.freq = freq
|
||||
assert idx.freq == freq
|
||||
assert isinstance(idx.freq, DateOffset)
|
||||
|
||||
# can reset to None
|
||||
idx._data.freq = None
|
||||
assert idx.freq is None
|
||||
|
||||
def test_freq_view_safe(self):
|
||||
# Setting the freq for one DatetimeIndex shouldn't alter the freq
|
||||
# for another that views the same data
|
||||
|
||||
dti = date_range("2016-01-01", periods=5)
|
||||
dta = dti._data
|
||||
|
||||
dti2 = DatetimeIndex(dta)._with_freq(None)
|
||||
assert dti2.freq is None
|
||||
|
||||
# Original was not altered
|
||||
assert dti.freq == "D"
|
||||
assert dta.freq == "D"
|
@ -0,0 +1,779 @@
|
||||
from datetime import (
|
||||
date,
|
||||
datetime,
|
||||
time,
|
||||
timedelta,
|
||||
)
|
||||
|
||||
import numpy as np
|
||||
import pytest
|
||||
|
||||
from pandas.errors import InvalidIndexError
|
||||
|
||||
import pandas as pd
|
||||
from pandas import (
|
||||
DatetimeIndex,
|
||||
Index,
|
||||
Timestamp,
|
||||
bdate_range,
|
||||
date_range,
|
||||
notna,
|
||||
)
|
||||
import pandas._testing as tm
|
||||
|
||||
from pandas.tseries.frequencies import to_offset
|
||||
|
||||
START, END = datetime(2009, 1, 1), datetime(2010, 1, 1)
|
||||
|
||||
|
||||
class TestGetItem:
|
||||
def test_getitem_slice_keeps_name(self):
|
||||
# GH4226
|
||||
st = Timestamp("2013-07-01 00:00:00", tz="America/Los_Angeles")
|
||||
et = Timestamp("2013-07-02 00:00:00", tz="America/Los_Angeles")
|
||||
dr = date_range(st, et, freq="H", name="timebucket")
|
||||
assert dr[1:].name == dr.name
|
||||
|
||||
def test_getitem(self):
|
||||
idx1 = date_range("2011-01-01", "2011-01-31", freq="D", name="idx")
|
||||
idx2 = date_range(
|
||||
"2011-01-01", "2011-01-31", freq="D", tz="Asia/Tokyo", name="idx"
|
||||
)
|
||||
|
||||
for idx in [idx1, idx2]:
|
||||
result = idx[0]
|
||||
assert result == Timestamp("2011-01-01", tz=idx.tz)
|
||||
|
||||
result = idx[0:5]
|
||||
expected = date_range(
|
||||
"2011-01-01", "2011-01-05", freq="D", tz=idx.tz, name="idx"
|
||||
)
|
||||
tm.assert_index_equal(result, expected)
|
||||
assert result.freq == expected.freq
|
||||
|
||||
result = idx[0:10:2]
|
||||
expected = date_range(
|
||||
"2011-01-01", "2011-01-09", freq="2D", tz=idx.tz, name="idx"
|
||||
)
|
||||
tm.assert_index_equal(result, expected)
|
||||
assert result.freq == expected.freq
|
||||
|
||||
result = idx[-20:-5:3]
|
||||
expected = date_range(
|
||||
"2011-01-12", "2011-01-24", freq="3D", tz=idx.tz, name="idx"
|
||||
)
|
||||
tm.assert_index_equal(result, expected)
|
||||
assert result.freq == expected.freq
|
||||
|
||||
result = idx[4::-1]
|
||||
expected = DatetimeIndex(
|
||||
["2011-01-05", "2011-01-04", "2011-01-03", "2011-01-02", "2011-01-01"],
|
||||
freq="-1D",
|
||||
tz=idx.tz,
|
||||
name="idx",
|
||||
)
|
||||
tm.assert_index_equal(result, expected)
|
||||
assert result.freq == expected.freq
|
||||
|
||||
@pytest.mark.parametrize("freq", ["B", "C"])
|
||||
def test_dti_business_getitem(self, freq):
|
||||
rng = bdate_range(START, END, freq=freq)
|
||||
smaller = rng[:5]
|
||||
exp = DatetimeIndex(rng.view(np.ndarray)[:5], freq=freq)
|
||||
tm.assert_index_equal(smaller, exp)
|
||||
assert smaller.freq == exp.freq
|
||||
assert smaller.freq == rng.freq
|
||||
|
||||
sliced = rng[::5]
|
||||
assert sliced.freq == to_offset(freq) * 5
|
||||
|
||||
fancy_indexed = rng[[4, 3, 2, 1, 0]]
|
||||
assert len(fancy_indexed) == 5
|
||||
assert isinstance(fancy_indexed, DatetimeIndex)
|
||||
assert fancy_indexed.freq is None
|
||||
|
||||
# 32-bit vs. 64-bit platforms
|
||||
assert rng[4] == rng[np.int_(4)]
|
||||
|
||||
@pytest.mark.parametrize("freq", ["B", "C"])
|
||||
def test_dti_business_getitem_matplotlib_hackaround(self, freq):
|
||||
rng = bdate_range(START, END, freq=freq)
|
||||
with tm.assert_produces_warning(FutureWarning):
|
||||
# GH#30588 multi-dimensional indexing deprecated
|
||||
values = rng[:, None]
|
||||
expected = rng.values[:, None]
|
||||
tm.assert_numpy_array_equal(values, expected)
|
||||
|
||||
def test_getitem_int_list(self):
|
||||
dti = date_range(start="1/1/2005", end="12/1/2005", freq="M")
|
||||
dti2 = dti[[1, 3, 5]]
|
||||
|
||||
v1 = dti2[0]
|
||||
v2 = dti2[1]
|
||||
v3 = dti2[2]
|
||||
|
||||
assert v1 == Timestamp("2/28/2005")
|
||||
assert v2 == Timestamp("4/30/2005")
|
||||
assert v3 == Timestamp("6/30/2005")
|
||||
|
||||
# getitem with non-slice drops freq
|
||||
assert dti2.freq is None
|
||||
|
||||
|
||||
class TestWhere:
|
||||
def test_where_doesnt_retain_freq(self):
|
||||
dti = date_range("20130101", periods=3, freq="D", name="idx")
|
||||
cond = [True, True, False]
|
||||
expected = DatetimeIndex([dti[0], dti[1], dti[0]], freq=None, name="idx")
|
||||
|
||||
result = dti.where(cond, dti[::-1])
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
def test_where_other(self):
|
||||
# other is ndarray or Index
|
||||
i = date_range("20130101", periods=3, tz="US/Eastern")
|
||||
|
||||
for arr in [np.nan, pd.NaT]:
|
||||
result = i.where(notna(i), other=arr)
|
||||
expected = i
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
i2 = i.copy()
|
||||
i2 = Index([pd.NaT, pd.NaT] + i[2:].tolist())
|
||||
result = i.where(notna(i2), i2)
|
||||
tm.assert_index_equal(result, i2)
|
||||
|
||||
i2 = i.copy()
|
||||
i2 = Index([pd.NaT, pd.NaT] + i[2:].tolist())
|
||||
result = i.where(notna(i2), i2._values)
|
||||
tm.assert_index_equal(result, i2)
|
||||
|
||||
def test_where_invalid_dtypes(self):
|
||||
dti = date_range("20130101", periods=3, tz="US/Eastern")
|
||||
|
||||
tail = dti[2:].tolist()
|
||||
i2 = Index([pd.NaT, pd.NaT] + tail)
|
||||
|
||||
mask = notna(i2)
|
||||
|
||||
# passing tz-naive ndarray to tzaware DTI
|
||||
result = dti.where(mask, i2.values)
|
||||
expected = Index([pd.NaT.asm8, pd.NaT.asm8] + tail, dtype=object)
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
# passing tz-aware DTI to tznaive DTI
|
||||
naive = dti.tz_localize(None)
|
||||
result = naive.where(mask, i2)
|
||||
expected = Index([i2[0], i2[1]] + naive[2:].tolist(), dtype=object)
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
pi = i2.tz_localize(None).to_period("D")
|
||||
result = dti.where(mask, pi)
|
||||
expected = Index([pi[0], pi[1]] + tail, dtype=object)
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
tda = i2.asi8.view("timedelta64[ns]")
|
||||
result = dti.where(mask, tda)
|
||||
expected = Index([tda[0], tda[1]] + tail, dtype=object)
|
||||
assert isinstance(expected[0], np.timedelta64)
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
result = dti.where(mask, i2.asi8)
|
||||
expected = Index([pd.NaT.value, pd.NaT.value] + tail, dtype=object)
|
||||
assert isinstance(expected[0], int)
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
# non-matching scalar
|
||||
td = pd.Timedelta(days=4)
|
||||
result = dti.where(mask, td)
|
||||
expected = Index([td, td] + tail, dtype=object)
|
||||
assert expected[0] is td
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
def test_where_mismatched_nat(self, tz_aware_fixture):
|
||||
tz = tz_aware_fixture
|
||||
dti = date_range("2013-01-01", periods=3, tz=tz)
|
||||
cond = np.array([True, False, True])
|
||||
|
||||
tdnat = np.timedelta64("NaT", "ns")
|
||||
expected = Index([dti[0], tdnat, dti[2]], dtype=object)
|
||||
assert expected[1] is tdnat
|
||||
|
||||
result = dti.where(cond, tdnat)
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
def test_where_tz(self):
|
||||
i = date_range("20130101", periods=3, tz="US/Eastern")
|
||||
result = i.where(notna(i))
|
||||
expected = i
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
i2 = i.copy()
|
||||
i2 = Index([pd.NaT, pd.NaT] + i[2:].tolist())
|
||||
result = i.where(notna(i2))
|
||||
expected = i2
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
|
||||
class TestTake:
|
||||
def test_take_nan_first_datetime(self):
|
||||
index = DatetimeIndex([pd.NaT, Timestamp("20130101"), Timestamp("20130102")])
|
||||
result = index.take([-1, 0, 1])
|
||||
expected = DatetimeIndex([index[-1], index[0], index[1]])
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
def test_take(self):
|
||||
# GH#10295
|
||||
idx1 = date_range("2011-01-01", "2011-01-31", freq="D", name="idx")
|
||||
idx2 = date_range(
|
||||
"2011-01-01", "2011-01-31", freq="D", tz="Asia/Tokyo", name="idx"
|
||||
)
|
||||
|
||||
for idx in [idx1, idx2]:
|
||||
result = idx.take([0])
|
||||
assert result == Timestamp("2011-01-01", tz=idx.tz)
|
||||
|
||||
result = idx.take([0, 1, 2])
|
||||
expected = date_range(
|
||||
"2011-01-01", "2011-01-03", freq="D", tz=idx.tz, name="idx"
|
||||
)
|
||||
tm.assert_index_equal(result, expected)
|
||||
assert result.freq == expected.freq
|
||||
|
||||
result = idx.take([0, 2, 4])
|
||||
expected = date_range(
|
||||
"2011-01-01", "2011-01-05", freq="2D", tz=idx.tz, name="idx"
|
||||
)
|
||||
tm.assert_index_equal(result, expected)
|
||||
assert result.freq == expected.freq
|
||||
|
||||
result = idx.take([7, 4, 1])
|
||||
expected = date_range(
|
||||
"2011-01-08", "2011-01-02", freq="-3D", tz=idx.tz, name="idx"
|
||||
)
|
||||
tm.assert_index_equal(result, expected)
|
||||
assert result.freq == expected.freq
|
||||
|
||||
result = idx.take([3, 2, 5])
|
||||
expected = DatetimeIndex(
|
||||
["2011-01-04", "2011-01-03", "2011-01-06"],
|
||||
freq=None,
|
||||
tz=idx.tz,
|
||||
name="idx",
|
||||
)
|
||||
tm.assert_index_equal(result, expected)
|
||||
assert result.freq is None
|
||||
|
||||
result = idx.take([-3, 2, 5])
|
||||
expected = DatetimeIndex(
|
||||
["2011-01-29", "2011-01-03", "2011-01-06"],
|
||||
freq=None,
|
||||
tz=idx.tz,
|
||||
name="idx",
|
||||
)
|
||||
tm.assert_index_equal(result, expected)
|
||||
assert result.freq is None
|
||||
|
||||
def test_take_invalid_kwargs(self):
|
||||
idx = date_range("2011-01-01", "2011-01-31", freq="D", name="idx")
|
||||
indices = [1, 6, 5, 9, 10, 13, 15, 3]
|
||||
|
||||
msg = r"take\(\) got an unexpected keyword argument 'foo'"
|
||||
with pytest.raises(TypeError, match=msg):
|
||||
idx.take(indices, foo=2)
|
||||
|
||||
msg = "the 'out' parameter is not supported"
|
||||
with pytest.raises(ValueError, match=msg):
|
||||
idx.take(indices, out=indices)
|
||||
|
||||
msg = "the 'mode' parameter is not supported"
|
||||
with pytest.raises(ValueError, match=msg):
|
||||
idx.take(indices, mode="clip")
|
||||
|
||||
# TODO: This method came from test_datetime; de-dup with version above
|
||||
@pytest.mark.parametrize("tz", [None, "US/Eastern", "Asia/Tokyo"])
|
||||
def test_take2(self, tz):
|
||||
dates = [
|
||||
datetime(2010, 1, 1, 14),
|
||||
datetime(2010, 1, 1, 15),
|
||||
datetime(2010, 1, 1, 17),
|
||||
datetime(2010, 1, 1, 21),
|
||||
]
|
||||
|
||||
idx = date_range(
|
||||
start="2010-01-01 09:00",
|
||||
end="2010-02-01 09:00",
|
||||
freq="H",
|
||||
tz=tz,
|
||||
name="idx",
|
||||
)
|
||||
expected = DatetimeIndex(dates, freq=None, name="idx", tz=tz)
|
||||
|
||||
taken1 = idx.take([5, 6, 8, 12])
|
||||
taken2 = idx[[5, 6, 8, 12]]
|
||||
|
||||
for taken in [taken1, taken2]:
|
||||
tm.assert_index_equal(taken, expected)
|
||||
assert isinstance(taken, DatetimeIndex)
|
||||
assert taken.freq is None
|
||||
assert taken.tz == expected.tz
|
||||
assert taken.name == expected.name
|
||||
|
||||
def test_take_fill_value(self):
|
||||
# GH#12631
|
||||
idx = DatetimeIndex(["2011-01-01", "2011-02-01", "2011-03-01"], name="xxx")
|
||||
result = idx.take(np.array([1, 0, -1]))
|
||||
expected = DatetimeIndex(["2011-02-01", "2011-01-01", "2011-03-01"], name="xxx")
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
# fill_value
|
||||
result = idx.take(np.array([1, 0, -1]), fill_value=True)
|
||||
expected = DatetimeIndex(["2011-02-01", "2011-01-01", "NaT"], name="xxx")
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
# allow_fill=False
|
||||
result = idx.take(np.array([1, 0, -1]), allow_fill=False, fill_value=True)
|
||||
expected = DatetimeIndex(["2011-02-01", "2011-01-01", "2011-03-01"], name="xxx")
|
||||
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 = "out of bounds"
|
||||
with pytest.raises(IndexError, match=msg):
|
||||
idx.take(np.array([1, -5]))
|
||||
|
||||
def test_take_fill_value_with_timezone(self):
|
||||
idx = DatetimeIndex(
|
||||
["2011-01-01", "2011-02-01", "2011-03-01"], name="xxx", tz="US/Eastern"
|
||||
)
|
||||
result = idx.take(np.array([1, 0, -1]))
|
||||
expected = DatetimeIndex(
|
||||
["2011-02-01", "2011-01-01", "2011-03-01"], name="xxx", tz="US/Eastern"
|
||||
)
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
# fill_value
|
||||
result = idx.take(np.array([1, 0, -1]), fill_value=True)
|
||||
expected = DatetimeIndex(
|
||||
["2011-02-01", "2011-01-01", "NaT"], name="xxx", tz="US/Eastern"
|
||||
)
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
# allow_fill=False
|
||||
result = idx.take(np.array([1, 0, -1]), allow_fill=False, fill_value=True)
|
||||
expected = DatetimeIndex(
|
||||
["2011-02-01", "2011-01-01", "2011-03-01"], name="xxx", tz="US/Eastern"
|
||||
)
|
||||
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 = "out of bounds"
|
||||
with pytest.raises(IndexError, match=msg):
|
||||
idx.take(np.array([1, -5]))
|
||||
|
||||
|
||||
class TestGetLoc:
|
||||
@pytest.mark.parametrize("method", [None, "pad", "backfill", "nearest"])
|
||||
@pytest.mark.filterwarnings("ignore:Passing method:FutureWarning")
|
||||
def test_get_loc_method_exact_match(self, method):
|
||||
idx = date_range("2000-01-01", periods=3)
|
||||
assert idx.get_loc(idx[1], method) == 1
|
||||
assert idx.get_loc(idx[1].to_pydatetime(), method) == 1
|
||||
assert idx.get_loc(str(idx[1]), method) == 1
|
||||
|
||||
if method is not None:
|
||||
assert idx.get_loc(idx[1], method, tolerance=pd.Timedelta("0 days")) == 1
|
||||
|
||||
@pytest.mark.filterwarnings("ignore:Passing method:FutureWarning")
|
||||
def test_get_loc(self):
|
||||
idx = date_range("2000-01-01", periods=3)
|
||||
|
||||
assert idx.get_loc("2000-01-01", method="nearest") == 0
|
||||
assert idx.get_loc("2000-01-01T12", method="nearest") == 1
|
||||
|
||||
assert idx.get_loc("2000-01-01T12", method="nearest", tolerance="1 day") == 1
|
||||
assert (
|
||||
idx.get_loc("2000-01-01T12", method="nearest", tolerance=pd.Timedelta("1D"))
|
||||
== 1
|
||||
)
|
||||
assert (
|
||||
idx.get_loc(
|
||||
"2000-01-01T12", method="nearest", tolerance=np.timedelta64(1, "D")
|
||||
)
|
||||
== 1
|
||||
)
|
||||
assert (
|
||||
idx.get_loc("2000-01-01T12", method="nearest", tolerance=timedelta(1)) == 1
|
||||
)
|
||||
with pytest.raises(ValueError, match="unit abbreviation w/o a number"):
|
||||
idx.get_loc("2000-01-01T12", method="nearest", tolerance="foo")
|
||||
with pytest.raises(KeyError, match="'2000-01-01T03'"):
|
||||
idx.get_loc("2000-01-01T03", method="nearest", tolerance="2 hours")
|
||||
with pytest.raises(
|
||||
ValueError, match="tolerance size must match target index size"
|
||||
):
|
||||
idx.get_loc(
|
||||
"2000-01-01",
|
||||
method="nearest",
|
||||
tolerance=[
|
||||
pd.Timedelta("1day").to_timedelta64(),
|
||||
pd.Timedelta("1day").to_timedelta64(),
|
||||
],
|
||||
)
|
||||
|
||||
assert idx.get_loc("2000", method="nearest") == slice(0, 3)
|
||||
assert idx.get_loc("2000-01", method="nearest") == slice(0, 3)
|
||||
|
||||
assert idx.get_loc("1999", method="nearest") == 0
|
||||
assert idx.get_loc("2001", method="nearest") == 2
|
||||
|
||||
with pytest.raises(KeyError, match="'1999'"):
|
||||
idx.get_loc("1999", method="pad")
|
||||
with pytest.raises(KeyError, match="'2001'"):
|
||||
idx.get_loc("2001", method="backfill")
|
||||
|
||||
with pytest.raises(KeyError, match="'foobar'"):
|
||||
idx.get_loc("foobar")
|
||||
with pytest.raises(InvalidIndexError, match=r"slice\(None, 2, None\)"):
|
||||
idx.get_loc(slice(2))
|
||||
|
||||
idx = DatetimeIndex(["2000-01-01", "2000-01-04"])
|
||||
assert idx.get_loc("2000-01-02", method="nearest") == 0
|
||||
assert idx.get_loc("2000-01-03", method="nearest") == 1
|
||||
assert idx.get_loc("2000-01", method="nearest") == slice(0, 2)
|
||||
|
||||
def test_get_loc_time_obj(self):
|
||||
# time indexing
|
||||
idx = date_range("2000-01-01", periods=24, freq="H")
|
||||
|
||||
result = idx.get_loc(time(12))
|
||||
expected = np.array([12])
|
||||
tm.assert_numpy_array_equal(result, expected, check_dtype=False)
|
||||
|
||||
result = idx.get_loc(time(12, 30))
|
||||
expected = np.array([])
|
||||
tm.assert_numpy_array_equal(result, expected, check_dtype=False)
|
||||
|
||||
msg = "cannot yet lookup inexact labels when key is a time object"
|
||||
with pytest.raises(NotImplementedError, match=msg):
|
||||
with tm.assert_produces_warning(FutureWarning, match="deprecated"):
|
||||
idx.get_loc(time(12, 30), method="pad")
|
||||
|
||||
def test_get_loc_time_obj2(self):
|
||||
# GH#8667
|
||||
|
||||
from pandas._libs.index import _SIZE_CUTOFF
|
||||
|
||||
ns = _SIZE_CUTOFF + np.array([-100, 100], dtype=np.int64)
|
||||
key = time(15, 11, 30)
|
||||
start = key.hour * 3600 + key.minute * 60 + key.second
|
||||
step = 24 * 3600
|
||||
|
||||
for n in ns:
|
||||
idx = date_range("2014-11-26", periods=n, freq="S")
|
||||
ts = pd.Series(np.random.randn(n), index=idx)
|
||||
locs = np.arange(start, n, step, dtype=np.intp)
|
||||
|
||||
result = ts.index.get_loc(key)
|
||||
tm.assert_numpy_array_equal(result, locs)
|
||||
tm.assert_series_equal(ts[key], ts.iloc[locs])
|
||||
|
||||
left, right = ts.copy(), ts.copy()
|
||||
left[key] *= -10
|
||||
right.iloc[locs] *= -10
|
||||
tm.assert_series_equal(left, right)
|
||||
|
||||
def test_get_loc_time_nat(self):
|
||||
# GH#35114
|
||||
# Case where key's total microseconds happens to match iNaT % 1e6 // 1000
|
||||
tic = time(minute=12, second=43, microsecond=145224)
|
||||
dti = DatetimeIndex([pd.NaT])
|
||||
|
||||
loc = dti.get_loc(tic)
|
||||
expected = np.array([], dtype=np.intp)
|
||||
tm.assert_numpy_array_equal(loc, expected)
|
||||
|
||||
def test_get_loc_tz_aware(self):
|
||||
# https://github.com/pandas-dev/pandas/issues/32140
|
||||
dti = date_range(
|
||||
Timestamp("2019-12-12 00:00:00", tz="US/Eastern"),
|
||||
Timestamp("2019-12-13 00:00:00", tz="US/Eastern"),
|
||||
freq="5s",
|
||||
)
|
||||
key = Timestamp("2019-12-12 10:19:25", tz="US/Eastern")
|
||||
with tm.assert_produces_warning(FutureWarning, match="deprecated"):
|
||||
result = dti.get_loc(key, method="nearest")
|
||||
assert result == 7433
|
||||
|
||||
def test_get_loc_nat(self):
|
||||
# GH#20464
|
||||
index = DatetimeIndex(["1/3/2000", "NaT"])
|
||||
assert index.get_loc(pd.NaT) == 1
|
||||
|
||||
assert index.get_loc(None) == 1
|
||||
|
||||
assert index.get_loc(np.nan) == 1
|
||||
|
||||
assert index.get_loc(pd.NA) == 1
|
||||
|
||||
assert index.get_loc(np.datetime64("NaT")) == 1
|
||||
|
||||
with pytest.raises(KeyError, match="NaT"):
|
||||
index.get_loc(np.timedelta64("NaT"))
|
||||
|
||||
@pytest.mark.parametrize("key", [pd.Timedelta(0), pd.Timedelta(1), timedelta(0)])
|
||||
def test_get_loc_timedelta_invalid_key(self, key):
|
||||
# GH#20464
|
||||
dti = date_range("1970-01-01", periods=10)
|
||||
msg = "Cannot index DatetimeIndex with [Tt]imedelta"
|
||||
with pytest.raises(TypeError, match=msg):
|
||||
dti.get_loc(key)
|
||||
|
||||
def test_get_loc_reasonable_key_error(self):
|
||||
# GH#1062
|
||||
index = DatetimeIndex(["1/3/2000"])
|
||||
with pytest.raises(KeyError, match="2000"):
|
||||
index.get_loc("1/1/2000")
|
||||
|
||||
def test_get_loc_year_str(self):
|
||||
rng = date_range("1/1/2000", "1/1/2010")
|
||||
|
||||
result = rng.get_loc("2009")
|
||||
expected = slice(3288, 3653)
|
||||
assert result == expected
|
||||
|
||||
|
||||
class TestContains:
|
||||
def test_dti_contains_with_duplicates(self):
|
||||
d = datetime(2011, 12, 5, 20, 30)
|
||||
ix = DatetimeIndex([d, d])
|
||||
assert d in ix
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"vals",
|
||||
[
|
||||
[0, 1, 0],
|
||||
[0, 0, -1],
|
||||
[0, -1, -1],
|
||||
["2015", "2015", "2016"],
|
||||
["2015", "2015", "2014"],
|
||||
],
|
||||
)
|
||||
def test_contains_nonunique(self, vals):
|
||||
# GH#9512
|
||||
idx = DatetimeIndex(vals)
|
||||
assert idx[0] in idx
|
||||
|
||||
|
||||
class TestGetIndexer:
|
||||
def test_get_indexer_date_objs(self):
|
||||
rng = date_range("1/1/2000", periods=20)
|
||||
|
||||
result = rng.get_indexer(rng.map(lambda x: x.date()))
|
||||
expected = rng.get_indexer(rng)
|
||||
tm.assert_numpy_array_equal(result, expected)
|
||||
|
||||
def test_get_indexer(self):
|
||||
idx = date_range("2000-01-01", periods=3)
|
||||
exp = np.array([0, 1, 2], dtype=np.intp)
|
||||
tm.assert_numpy_array_equal(idx.get_indexer(idx), exp)
|
||||
|
||||
target = idx[0] + pd.to_timedelta(["-1 hour", "12 hours", "1 day 1 hour"])
|
||||
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=pd.Timedelta("1 hour")),
|
||||
np.array([0, -1, 1], dtype=np.intp),
|
||||
)
|
||||
tol_raw = [
|
||||
pd.Timedelta("1 hour"),
|
||||
pd.Timedelta("1 hour"),
|
||||
pd.Timedelta("1 hour").to_timedelta64(),
|
||||
]
|
||||
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 = [
|
||||
pd.Timedelta("2 hour").to_timedelta64(),
|
||||
pd.Timedelta("1 hour").to_timedelta64(),
|
||||
"foo",
|
||||
]
|
||||
msg = "Could not convert 'foo' to NumPy timedelta"
|
||||
with pytest.raises(ValueError, match=msg):
|
||||
idx.get_indexer(target, "nearest", tolerance=tol_bad)
|
||||
with pytest.raises(ValueError, match="abbreviation w/o a number"):
|
||||
idx.get_indexer(idx[[0]], method="nearest", tolerance="foo")
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"target",
|
||||
[
|
||||
[date(2020, 1, 1), Timestamp("2020-01-02")],
|
||||
[Timestamp("2020-01-01"), date(2020, 1, 2)],
|
||||
],
|
||||
)
|
||||
def test_get_indexer_mixed_dtypes(self, target):
|
||||
# https://github.com/pandas-dev/pandas/issues/33741
|
||||
values = DatetimeIndex([Timestamp("2020-01-01"), Timestamp("2020-01-02")])
|
||||
result = values.get_indexer(target)
|
||||
expected = np.array([0, 1], dtype=np.intp)
|
||||
tm.assert_numpy_array_equal(result, expected)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"target, positions",
|
||||
[
|
||||
([date(9999, 1, 1), Timestamp("2020-01-01")], [-1, 0]),
|
||||
([Timestamp("2020-01-01"), date(9999, 1, 1)], [0, -1]),
|
||||
([date(9999, 1, 1), date(9999, 1, 1)], [-1, -1]),
|
||||
],
|
||||
)
|
||||
@pytest.mark.filterwarnings("ignore:Comparison of Timestamp.*:FutureWarning")
|
||||
def test_get_indexer_out_of_bounds_date(self, target, positions):
|
||||
values = DatetimeIndex([Timestamp("2020-01-01"), Timestamp("2020-01-02")])
|
||||
|
||||
result = values.get_indexer(target)
|
||||
expected = np.array(positions, dtype=np.intp)
|
||||
tm.assert_numpy_array_equal(result, expected)
|
||||
|
||||
def test_get_indexer_pad_requires_monotonicity(self):
|
||||
rng = date_range("1/1/2000", "3/1/2000", freq="B")
|
||||
|
||||
# neither monotonic increasing or decreasing
|
||||
rng2 = rng[[1, 0, 2]]
|
||||
|
||||
msg = "index must be monotonic increasing or decreasing"
|
||||
with pytest.raises(ValueError, match=msg):
|
||||
rng2.get_indexer(rng, method="pad")
|
||||
|
||||
|
||||
class TestMaybeCastSliceBound:
|
||||
def test_maybe_cast_slice_bounds_empty(self):
|
||||
# GH#14354
|
||||
empty_idx = date_range(freq="1H", periods=0, end="2015")
|
||||
|
||||
right = empty_idx._maybe_cast_slice_bound("2015-01-02", "right")
|
||||
exp = Timestamp("2015-01-02 23:59:59.999999999")
|
||||
assert right == exp
|
||||
|
||||
left = empty_idx._maybe_cast_slice_bound("2015-01-02", "left")
|
||||
exp = Timestamp("2015-01-02 00:00:00")
|
||||
assert left == exp
|
||||
|
||||
def test_maybe_cast_slice_duplicate_monotonic(self):
|
||||
# https://github.com/pandas-dev/pandas/issues/16515
|
||||
idx = DatetimeIndex(["2017", "2017"])
|
||||
result = idx._maybe_cast_slice_bound("2017-01-01", "left")
|
||||
expected = Timestamp("2017-01-01")
|
||||
assert result == expected
|
||||
|
||||
|
||||
class TestGetValue:
|
||||
def test_get_value(self):
|
||||
# specifically make sure we have test for np.datetime64 key
|
||||
dti = date_range("2016-01-01", periods=3)
|
||||
|
||||
arr = np.arange(6, 9)
|
||||
ser = pd.Series(arr, index=dti)
|
||||
|
||||
key = dti[1]
|
||||
|
||||
with pytest.raises(AttributeError, match="has no attribute '_values'"):
|
||||
with tm.assert_produces_warning(FutureWarning):
|
||||
dti.get_value(arr, key)
|
||||
|
||||
with tm.assert_produces_warning(FutureWarning):
|
||||
result = dti.get_value(ser, key)
|
||||
assert result == 7
|
||||
|
||||
with tm.assert_produces_warning(FutureWarning):
|
||||
result = dti.get_value(ser, key.to_pydatetime())
|
||||
assert result == 7
|
||||
|
||||
with tm.assert_produces_warning(FutureWarning):
|
||||
result = dti.get_value(ser, key.to_datetime64())
|
||||
assert result == 7
|
||||
|
||||
|
||||
class TestGetSliceBounds:
|
||||
@pytest.mark.parametrize("box", [date, datetime, Timestamp])
|
||||
@pytest.mark.parametrize("kind", ["getitem", "loc", None])
|
||||
@pytest.mark.parametrize("side, expected", [("left", 4), ("right", 5)])
|
||||
def test_get_slice_bounds_datetime_within(
|
||||
self, box, kind, side, expected, tz_aware_fixture
|
||||
):
|
||||
# GH 35690
|
||||
tz = tz_aware_fixture
|
||||
index = bdate_range("2000-01-03", "2000-02-11").tz_localize(tz)
|
||||
key = box(year=2000, month=1, day=7)
|
||||
|
||||
warn = None if tz is None else FutureWarning
|
||||
with tm.assert_produces_warning(warn):
|
||||
# GH#36148 will require tzawareness-compat
|
||||
result = index.get_slice_bound(key, kind=kind, side=side)
|
||||
assert result == expected
|
||||
|
||||
@pytest.mark.parametrize("box", [datetime, Timestamp])
|
||||
@pytest.mark.parametrize("kind", ["getitem", "loc", None])
|
||||
@pytest.mark.parametrize("side", ["left", "right"])
|
||||
@pytest.mark.parametrize("year, expected", [(1999, 0), (2020, 30)])
|
||||
def test_get_slice_bounds_datetime_outside(
|
||||
self, box, kind, side, year, expected, tz_aware_fixture
|
||||
):
|
||||
# GH 35690
|
||||
tz = tz_aware_fixture
|
||||
index = bdate_range("2000-01-03", "2000-02-11").tz_localize(tz)
|
||||
key = box(year=year, month=1, day=7)
|
||||
|
||||
warn = None if tz is None else FutureWarning
|
||||
with tm.assert_produces_warning(warn):
|
||||
# GH#36148 will require tzawareness-compat
|
||||
result = index.get_slice_bound(key, kind=kind, side=side)
|
||||
assert result == expected
|
||||
|
||||
@pytest.mark.parametrize("box", [datetime, Timestamp])
|
||||
@pytest.mark.parametrize("kind", ["getitem", "loc", None])
|
||||
def test_slice_datetime_locs(self, box, kind, tz_aware_fixture):
|
||||
# GH 34077
|
||||
tz = tz_aware_fixture
|
||||
index = DatetimeIndex(["2010-01-01", "2010-01-03"]).tz_localize(tz)
|
||||
key = box(2010, 1, 1)
|
||||
|
||||
warn = None if tz is None else FutureWarning
|
||||
with tm.assert_produces_warning(warn):
|
||||
# GH#36148 will require tzawareness-compat
|
||||
result = index.slice_locs(key, box(2010, 1, 2))
|
||||
expected = (0, 1)
|
||||
assert result == expected
|
||||
|
||||
|
||||
class TestIndexerBetweenTime:
|
||||
def test_indexer_between_time(self):
|
||||
# GH#11818
|
||||
rng = date_range("1/1/2000", "1/5/2000", freq="5min")
|
||||
msg = r"Cannot convert arg \[datetime\.datetime\(2010, 1, 2, 1, 0\)\] to a time"
|
||||
with pytest.raises(ValueError, match=msg):
|
||||
rng.indexer_between_time(datetime(2010, 1, 2, 1), datetime(2010, 1, 2, 5))
|
@ -0,0 +1,152 @@
|
||||
from datetime import datetime
|
||||
|
||||
import numpy as np
|
||||
import pytest
|
||||
|
||||
from pandas import (
|
||||
DatetimeIndex,
|
||||
Index,
|
||||
Timestamp,
|
||||
date_range,
|
||||
to_datetime,
|
||||
)
|
||||
import pandas._testing as tm
|
||||
|
||||
from pandas.tseries.offsets import (
|
||||
BDay,
|
||||
BMonthEnd,
|
||||
)
|
||||
|
||||
|
||||
class TestJoin:
|
||||
def test_does_not_convert_mixed_integer(self):
|
||||
df = tm.makeCustomDataframe(
|
||||
10,
|
||||
10,
|
||||
data_gen_f=lambda *args, **kwargs: np.random.randn(),
|
||||
r_idx_type="i",
|
||||
c_idx_type="dt",
|
||||
)
|
||||
cols = df.columns.join(df.index, how="outer")
|
||||
joined = cols.join(df.columns)
|
||||
assert cols.dtype == np.dtype("O")
|
||||
assert cols.dtype == joined.dtype
|
||||
tm.assert_numpy_array_equal(cols.values, joined.values)
|
||||
|
||||
def test_join_self(self, join_type):
|
||||
index = date_range("1/1/2000", periods=10)
|
||||
joined = index.join(index, how=join_type)
|
||||
assert index is joined
|
||||
|
||||
def test_join_with_period_index(self, join_type):
|
||||
df = tm.makeCustomDataframe(
|
||||
10,
|
||||
10,
|
||||
data_gen_f=lambda *args: np.random.randint(2),
|
||||
c_idx_type="p",
|
||||
r_idx_type="dt",
|
||||
)
|
||||
s = df.iloc[:5, 0]
|
||||
|
||||
expected = df.columns.astype("O").join(s.index, how=join_type)
|
||||
result = df.columns.join(s.index, how=join_type)
|
||||
tm.assert_index_equal(expected, result)
|
||||
|
||||
def test_join_object_index(self):
|
||||
rng = date_range("1/1/2000", periods=10)
|
||||
idx = Index(["a", "b", "c", "d"])
|
||||
|
||||
result = rng.join(idx, how="outer")
|
||||
assert isinstance(result[0], Timestamp)
|
||||
|
||||
def test_join_utc_convert(self, join_type):
|
||||
rng = date_range("1/1/2011", periods=100, freq="H", tz="utc")
|
||||
|
||||
left = rng.tz_convert("US/Eastern")
|
||||
right = rng.tz_convert("Europe/Berlin")
|
||||
|
||||
result = left.join(left[:-5], how=join_type)
|
||||
assert isinstance(result, DatetimeIndex)
|
||||
assert result.tz == left.tz
|
||||
|
||||
result = left.join(right[:-5], how=join_type)
|
||||
assert isinstance(result, DatetimeIndex)
|
||||
assert result.tz.zone == "UTC"
|
||||
|
||||
def test_datetimeindex_union_join_empty(self, sort):
|
||||
dti = date_range(start="1/1/2001", end="2/1/2001", freq="D")
|
||||
empty = Index([])
|
||||
|
||||
result = dti.union(empty, sort=sort)
|
||||
expected = dti.astype("O")
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
result = dti.join(empty)
|
||||
assert isinstance(result, DatetimeIndex)
|
||||
tm.assert_index_equal(result, dti)
|
||||
|
||||
def test_join_nonunique(self):
|
||||
idx1 = to_datetime(["2012-11-06 16:00:11.477563", "2012-11-06 16:00:11.477563"])
|
||||
idx2 = to_datetime(["2012-11-06 15:11:09.006507", "2012-11-06 15:11:09.006507"])
|
||||
rs = idx1.join(idx2, how="outer")
|
||||
assert rs.is_monotonic
|
||||
|
||||
@pytest.mark.parametrize("freq", ["B", "C"])
|
||||
def test_outer_join(self, freq):
|
||||
# should just behave as union
|
||||
start, end = datetime(2009, 1, 1), datetime(2010, 1, 1)
|
||||
rng = date_range(start=start, end=end, freq=freq)
|
||||
|
||||
# overlapping
|
||||
left = rng[:10]
|
||||
right = rng[5:10]
|
||||
|
||||
the_join = left.join(right, how="outer")
|
||||
assert isinstance(the_join, DatetimeIndex)
|
||||
|
||||
# non-overlapping, gap in middle
|
||||
left = rng[:5]
|
||||
right = rng[10:]
|
||||
|
||||
the_join = left.join(right, how="outer")
|
||||
assert isinstance(the_join, DatetimeIndex)
|
||||
assert the_join.freq is None
|
||||
|
||||
# non-overlapping, no gap
|
||||
left = rng[:5]
|
||||
right = rng[5:10]
|
||||
|
||||
the_join = left.join(right, how="outer")
|
||||
assert isinstance(the_join, DatetimeIndex)
|
||||
|
||||
# overlapping, but different offset
|
||||
other = date_range(start, end, freq=BMonthEnd())
|
||||
|
||||
the_join = rng.join(other, how="outer")
|
||||
assert isinstance(the_join, DatetimeIndex)
|
||||
assert the_join.freq is None
|
||||
|
||||
def test_naive_aware_conflicts(self):
|
||||
start, end = datetime(2009, 1, 1), datetime(2010, 1, 1)
|
||||
naive = date_range(start, end, freq=BDay(), tz=None)
|
||||
aware = date_range(start, end, freq=BDay(), tz="Asia/Hong_Kong")
|
||||
|
||||
msg = "tz-naive.*tz-aware"
|
||||
with pytest.raises(TypeError, match=msg):
|
||||
naive.join(aware)
|
||||
|
||||
with pytest.raises(TypeError, match=msg):
|
||||
aware.join(naive)
|
||||
|
||||
@pytest.mark.parametrize("tz", [None, "US/Pacific"])
|
||||
def test_join_preserves_freq(self, tz):
|
||||
# GH#32157
|
||||
dti = date_range("2016-01-01", periods=10, tz=tz)
|
||||
result = dti[:5].join(dti[5:], how="outer")
|
||||
assert result.freq == dti.freq
|
||||
tm.assert_index_equal(result, dti)
|
||||
|
||||
result = dti[:5].join(dti[6:], how="outer")
|
||||
assert result.freq is None
|
||||
expected = dti.delete(5)
|
||||
tm.assert_index_equal(result, expected)
|
@ -0,0 +1,47 @@
|
||||
import pytest
|
||||
|
||||
from pandas import (
|
||||
DatetimeIndex,
|
||||
Index,
|
||||
MultiIndex,
|
||||
Period,
|
||||
date_range,
|
||||
)
|
||||
import pandas._testing as tm
|
||||
|
||||
|
||||
class TestMap:
|
||||
def test_map(self):
|
||||
rng = date_range("1/1/2000", periods=10)
|
||||
|
||||
f = lambda x: x.strftime("%Y%m%d")
|
||||
result = rng.map(f)
|
||||
exp = Index([f(x) for x in rng], dtype="<U8")
|
||||
tm.assert_index_equal(result, exp)
|
||||
|
||||
def test_map_fallthrough(self, capsys):
|
||||
# GH#22067, check we don't get warnings about silently ignored errors
|
||||
dti = date_range("2017-01-01", "2018-01-01", freq="B")
|
||||
|
||||
dti.map(lambda x: Period(year=x.year, month=x.month, freq="M"))
|
||||
|
||||
captured = capsys.readouterr()
|
||||
assert captured.err == ""
|
||||
|
||||
def test_map_bug_1677(self):
|
||||
index = DatetimeIndex(["2012-04-25 09:30:00.393000"])
|
||||
f = index.asof
|
||||
|
||||
result = index.map(f)
|
||||
expected = Index([f(index[0])])
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
@pytest.mark.parametrize("name", [None, "name"])
|
||||
def test_index_map(self, name):
|
||||
# see GH#20990
|
||||
count = 6
|
||||
index = date_range("2018-01-01", periods=count, freq="M", name=name).map(
|
||||
lambda x: (x.year, x.month)
|
||||
)
|
||||
exp_index = MultiIndex.from_product(((2018,), range(1, 7)), names=[name, name])
|
||||
tm.assert_index_equal(index, exp_index)
|
@ -0,0 +1,308 @@
|
||||
import calendar
|
||||
from datetime import datetime
|
||||
import locale
|
||||
import unicodedata
|
||||
|
||||
import numpy as np
|
||||
import pytest
|
||||
|
||||
import pandas as pd
|
||||
from pandas import (
|
||||
DatetimeIndex,
|
||||
Index,
|
||||
Timedelta,
|
||||
Timestamp,
|
||||
date_range,
|
||||
offsets,
|
||||
)
|
||||
import pandas._testing as tm
|
||||
from pandas.core.arrays import DatetimeArray
|
||||
|
||||
|
||||
class TestDatetime64:
|
||||
def test_no_millisecond_field(self):
|
||||
msg = "type object 'DatetimeIndex' has no attribute 'millisecond'"
|
||||
with pytest.raises(AttributeError, match=msg):
|
||||
DatetimeIndex.millisecond
|
||||
|
||||
msg = "'DatetimeIndex' object has no attribute 'millisecond'"
|
||||
with pytest.raises(AttributeError, match=msg):
|
||||
DatetimeIndex([]).millisecond
|
||||
|
||||
def test_datetimeindex_accessors(self):
|
||||
dti_naive = date_range(freq="D", start=datetime(1998, 1, 1), periods=365)
|
||||
# GH#13303
|
||||
dti_tz = date_range(
|
||||
freq="D", start=datetime(1998, 1, 1), periods=365, tz="US/Eastern"
|
||||
)
|
||||
for dti in [dti_naive, dti_tz]:
|
||||
|
||||
assert dti.year[0] == 1998
|
||||
assert dti.month[0] == 1
|
||||
assert dti.day[0] == 1
|
||||
assert dti.hour[0] == 0
|
||||
assert dti.minute[0] == 0
|
||||
assert dti.second[0] == 0
|
||||
assert dti.microsecond[0] == 0
|
||||
assert dti.dayofweek[0] == 3
|
||||
|
||||
assert dti.dayofyear[0] == 1
|
||||
assert dti.dayofyear[120] == 121
|
||||
|
||||
assert dti.isocalendar().week[0] == 1
|
||||
assert dti.isocalendar().week[120] == 18
|
||||
|
||||
assert dti.quarter[0] == 1
|
||||
assert dti.quarter[120] == 2
|
||||
|
||||
assert dti.days_in_month[0] == 31
|
||||
assert dti.days_in_month[90] == 30
|
||||
|
||||
assert dti.is_month_start[0]
|
||||
assert not dti.is_month_start[1]
|
||||
assert dti.is_month_start[31]
|
||||
assert dti.is_quarter_start[0]
|
||||
assert dti.is_quarter_start[90]
|
||||
assert dti.is_year_start[0]
|
||||
assert not dti.is_year_start[364]
|
||||
assert not dti.is_month_end[0]
|
||||
assert dti.is_month_end[30]
|
||||
assert not dti.is_month_end[31]
|
||||
assert dti.is_month_end[364]
|
||||
assert not dti.is_quarter_end[0]
|
||||
assert not dti.is_quarter_end[30]
|
||||
assert dti.is_quarter_end[89]
|
||||
assert dti.is_quarter_end[364]
|
||||
assert not dti.is_year_end[0]
|
||||
assert dti.is_year_end[364]
|
||||
|
||||
assert len(dti.year) == 365
|
||||
assert len(dti.month) == 365
|
||||
assert len(dti.day) == 365
|
||||
assert len(dti.hour) == 365
|
||||
assert len(dti.minute) == 365
|
||||
assert len(dti.second) == 365
|
||||
assert len(dti.microsecond) == 365
|
||||
assert len(dti.dayofweek) == 365
|
||||
assert len(dti.dayofyear) == 365
|
||||
assert len(dti.isocalendar()) == 365
|
||||
assert len(dti.quarter) == 365
|
||||
assert len(dti.is_month_start) == 365
|
||||
assert len(dti.is_month_end) == 365
|
||||
assert len(dti.is_quarter_start) == 365
|
||||
assert len(dti.is_quarter_end) == 365
|
||||
assert len(dti.is_year_start) == 365
|
||||
assert len(dti.is_year_end) == 365
|
||||
|
||||
dti.name = "name"
|
||||
|
||||
# non boolean accessors -> return Index
|
||||
for accessor in DatetimeArray._field_ops:
|
||||
if accessor in ["week", "weekofyear"]:
|
||||
# GH#33595 Deprecate week and weekofyear
|
||||
continue
|
||||
res = getattr(dti, accessor)
|
||||
assert len(res) == 365
|
||||
assert isinstance(res, Index)
|
||||
assert res.name == "name"
|
||||
|
||||
# boolean accessors -> return array
|
||||
for accessor in DatetimeArray._bool_ops:
|
||||
res = getattr(dti, accessor)
|
||||
assert len(res) == 365
|
||||
assert isinstance(res, np.ndarray)
|
||||
|
||||
# test boolean indexing
|
||||
res = dti[dti.is_quarter_start]
|
||||
exp = dti[[0, 90, 181, 273]]
|
||||
tm.assert_index_equal(res, exp)
|
||||
res = dti[dti.is_leap_year]
|
||||
exp = DatetimeIndex([], freq="D", tz=dti.tz, name="name")
|
||||
tm.assert_index_equal(res, exp)
|
||||
|
||||
def test_datetimeindex_accessors2(self):
|
||||
dti = date_range(freq="BQ-FEB", start=datetime(1998, 1, 1), periods=4)
|
||||
|
||||
assert sum(dti.is_quarter_start) == 0
|
||||
assert sum(dti.is_quarter_end) == 4
|
||||
assert sum(dti.is_year_start) == 0
|
||||
assert sum(dti.is_year_end) == 1
|
||||
|
||||
def test_datetimeindex_accessors3(self):
|
||||
# Ensure is_start/end accessors throw ValueError for CustomBusinessDay,
|
||||
bday_egypt = offsets.CustomBusinessDay(weekmask="Sun Mon Tue Wed Thu")
|
||||
dti = date_range(datetime(2013, 4, 30), periods=5, freq=bday_egypt)
|
||||
msg = "Custom business days is not supported by is_month_start"
|
||||
with pytest.raises(ValueError, match=msg):
|
||||
dti.is_month_start
|
||||
|
||||
def test_datetimeindex_accessors4(self):
|
||||
dti = DatetimeIndex(["2000-01-01", "2000-01-02", "2000-01-03"])
|
||||
|
||||
assert dti.is_month_start[0] == 1
|
||||
|
||||
def test_datetimeindex_accessors5(self):
|
||||
with tm.assert_produces_warning(FutureWarning, match="The 'freq' argument"):
|
||||
tests = [
|
||||
(Timestamp("2013-06-01", freq="M").is_month_start, 1),
|
||||
(Timestamp("2013-06-01", freq="BM").is_month_start, 0),
|
||||
(Timestamp("2013-06-03", freq="M").is_month_start, 0),
|
||||
(Timestamp("2013-06-03", freq="BM").is_month_start, 1),
|
||||
(Timestamp("2013-02-28", freq="Q-FEB").is_month_end, 1),
|
||||
(Timestamp("2013-02-28", freq="Q-FEB").is_quarter_end, 1),
|
||||
(Timestamp("2013-02-28", freq="Q-FEB").is_year_end, 1),
|
||||
(Timestamp("2013-03-01", freq="Q-FEB").is_month_start, 1),
|
||||
(Timestamp("2013-03-01", freq="Q-FEB").is_quarter_start, 1),
|
||||
(Timestamp("2013-03-01", freq="Q-FEB").is_year_start, 1),
|
||||
(Timestamp("2013-03-31", freq="QS-FEB").is_month_end, 1),
|
||||
(Timestamp("2013-03-31", freq="QS-FEB").is_quarter_end, 0),
|
||||
(Timestamp("2013-03-31", freq="QS-FEB").is_year_end, 0),
|
||||
(Timestamp("2013-02-01", freq="QS-FEB").is_month_start, 1),
|
||||
(Timestamp("2013-02-01", freq="QS-FEB").is_quarter_start, 1),
|
||||
(Timestamp("2013-02-01", freq="QS-FEB").is_year_start, 1),
|
||||
(Timestamp("2013-06-30", freq="BQ").is_month_end, 0),
|
||||
(Timestamp("2013-06-30", freq="BQ").is_quarter_end, 0),
|
||||
(Timestamp("2013-06-30", freq="BQ").is_year_end, 0),
|
||||
(Timestamp("2013-06-28", freq="BQ").is_month_end, 1),
|
||||
(Timestamp("2013-06-28", freq="BQ").is_quarter_end, 1),
|
||||
(Timestamp("2013-06-28", freq="BQ").is_year_end, 0),
|
||||
(Timestamp("2013-06-30", freq="BQS-APR").is_month_end, 0),
|
||||
(Timestamp("2013-06-30", freq="BQS-APR").is_quarter_end, 0),
|
||||
(Timestamp("2013-06-30", freq="BQS-APR").is_year_end, 0),
|
||||
(Timestamp("2013-06-28", freq="BQS-APR").is_month_end, 1),
|
||||
(Timestamp("2013-06-28", freq="BQS-APR").is_quarter_end, 1),
|
||||
(Timestamp("2013-03-29", freq="BQS-APR").is_year_end, 1),
|
||||
(Timestamp("2013-11-01", freq="AS-NOV").is_year_start, 1),
|
||||
(Timestamp("2013-10-31", freq="AS-NOV").is_year_end, 1),
|
||||
(Timestamp("2012-02-01").days_in_month, 29),
|
||||
(Timestamp("2013-02-01").days_in_month, 28),
|
||||
]
|
||||
|
||||
for ts, value in tests:
|
||||
assert ts == value
|
||||
|
||||
def test_datetimeindex_accessors6(self):
|
||||
# GH 6538: Check that DatetimeIndex and its TimeStamp elements
|
||||
# return the same weekofyear accessor close to new year w/ tz
|
||||
dates = ["2013/12/29", "2013/12/30", "2013/12/31"]
|
||||
dates = DatetimeIndex(dates, tz="Europe/Brussels")
|
||||
expected = [52, 1, 1]
|
||||
assert dates.isocalendar().week.tolist() == expected
|
||||
assert [d.weekofyear for d in dates] == expected
|
||||
|
||||
# GH 12806
|
||||
# error: Unsupported operand types for + ("List[None]" and "List[str]")
|
||||
@pytest.mark.parametrize(
|
||||
"time_locale", [None] + (tm.get_locales() or []) # type: ignore[operator]
|
||||
)
|
||||
def test_datetime_name_accessors(self, time_locale):
|
||||
# Test Monday -> Sunday and January -> December, in that sequence
|
||||
if time_locale is None:
|
||||
# If the time_locale is None, day-name and month_name should
|
||||
# return the english attributes
|
||||
expected_days = [
|
||||
"Monday",
|
||||
"Tuesday",
|
||||
"Wednesday",
|
||||
"Thursday",
|
||||
"Friday",
|
||||
"Saturday",
|
||||
"Sunday",
|
||||
]
|
||||
expected_months = [
|
||||
"January",
|
||||
"February",
|
||||
"March",
|
||||
"April",
|
||||
"May",
|
||||
"June",
|
||||
"July",
|
||||
"August",
|
||||
"September",
|
||||
"October",
|
||||
"November",
|
||||
"December",
|
||||
]
|
||||
else:
|
||||
with tm.set_locale(time_locale, locale.LC_TIME):
|
||||
expected_days = calendar.day_name[:]
|
||||
expected_months = calendar.month_name[1:]
|
||||
|
||||
# GH#11128
|
||||
dti = date_range(freq="D", start=datetime(1998, 1, 1), periods=365)
|
||||
english_days = [
|
||||
"Monday",
|
||||
"Tuesday",
|
||||
"Wednesday",
|
||||
"Thursday",
|
||||
"Friday",
|
||||
"Saturday",
|
||||
"Sunday",
|
||||
]
|
||||
for day, name, eng_name in zip(range(4, 11), expected_days, english_days):
|
||||
name = name.capitalize()
|
||||
assert dti.day_name(locale=time_locale)[day] == name
|
||||
assert dti.day_name(locale=None)[day] == eng_name
|
||||
ts = Timestamp(datetime(2016, 4, day))
|
||||
assert ts.day_name(locale=time_locale) == name
|
||||
dti = dti.append(DatetimeIndex([pd.NaT]))
|
||||
assert np.isnan(dti.day_name(locale=time_locale)[-1])
|
||||
ts = Timestamp(pd.NaT)
|
||||
assert np.isnan(ts.day_name(locale=time_locale))
|
||||
|
||||
# GH#12805
|
||||
dti = date_range(freq="M", start="2012", end="2013")
|
||||
result = dti.month_name(locale=time_locale)
|
||||
expected = Index([month.capitalize() for month in expected_months])
|
||||
|
||||
# work around different normalization schemes
|
||||
# https://github.com/pandas-dev/pandas/issues/22342
|
||||
result = result.str.normalize("NFD")
|
||||
expected = expected.str.normalize("NFD")
|
||||
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
for date, expected in zip(dti, expected_months):
|
||||
result = date.month_name(locale=time_locale)
|
||||
expected = expected.capitalize()
|
||||
|
||||
result = unicodedata.normalize("NFD", result)
|
||||
expected = unicodedata.normalize("NFD", result)
|
||||
|
||||
assert result == expected
|
||||
dti = dti.append(DatetimeIndex([pd.NaT]))
|
||||
assert np.isnan(dti.month_name(locale=time_locale)[-1])
|
||||
|
||||
def test_nanosecond_field(self):
|
||||
dti = DatetimeIndex(np.arange(10))
|
||||
|
||||
tm.assert_index_equal(dti.nanosecond, Index(np.arange(10, dtype=np.int64)))
|
||||
|
||||
|
||||
def test_iter_readonly():
|
||||
# GH#28055 ints_to_pydatetime with readonly array
|
||||
arr = np.array([np.datetime64("2012-02-15T12:00:00.000000000")])
|
||||
arr.setflags(write=False)
|
||||
dti = pd.to_datetime(arr)
|
||||
list(dti)
|
||||
|
||||
|
||||
def test_week_and_weekofyear_are_deprecated():
|
||||
# GH#33595 Deprecate week and weekofyear
|
||||
idx = date_range(start="2019-12-29", freq="D", periods=4)
|
||||
with tm.assert_produces_warning(FutureWarning):
|
||||
idx.week
|
||||
with tm.assert_produces_warning(FutureWarning):
|
||||
idx.weekofyear
|
||||
|
||||
|
||||
def test_add_timedelta_preserves_freq():
|
||||
# GH#37295 should hold for any DTI with freq=None or Tick freq
|
||||
tz = "Canada/Eastern"
|
||||
dti = date_range(
|
||||
start=Timestamp("2019-03-26 00:00:00-0400", tz=tz),
|
||||
end=Timestamp("2020-10-17 00:00:00-0400", tz=tz),
|
||||
freq="D",
|
||||
)
|
||||
result = dti + Timedelta(days=1)
|
||||
assert result.freq == dti.freq
|
@ -0,0 +1,13 @@
|
||||
import numpy as np
|
||||
|
||||
from pandas import date_range
|
||||
import pandas._testing as tm
|
||||
|
||||
|
||||
class TestSplit:
|
||||
def test_split_non_utc(self):
|
||||
# GH#14042
|
||||
indices = date_range("2016-01-01 00:00:00+0200", freq="S", periods=10)
|
||||
result = np.split(indices, indices_or_sections=[])[0]
|
||||
expected = indices._with_freq(None)
|
||||
tm.assert_index_equal(result, expected)
|
@ -0,0 +1,85 @@
|
||||
from datetime import datetime
|
||||
|
||||
from dateutil.tz import tzlocal
|
||||
import pytest
|
||||
|
||||
from pandas.compat import IS64
|
||||
|
||||
from pandas import (
|
||||
DatetimeIndex,
|
||||
Index,
|
||||
bdate_range,
|
||||
date_range,
|
||||
)
|
||||
import pandas._testing as tm
|
||||
|
||||
START, END = datetime(2009, 1, 1), datetime(2010, 1, 1)
|
||||
|
||||
|
||||
class TestDatetimeIndexOps:
|
||||
@pytest.mark.parametrize(
|
||||
"freq,expected",
|
||||
[
|
||||
("A", "day"),
|
||||
("Q", "day"),
|
||||
("M", "day"),
|
||||
("D", "day"),
|
||||
("H", "hour"),
|
||||
("T", "minute"),
|
||||
("S", "second"),
|
||||
("L", "millisecond"),
|
||||
("U", "microsecond"),
|
||||
],
|
||||
)
|
||||
def test_resolution(self, request, tz_naive_fixture, freq, expected):
|
||||
tz = tz_naive_fixture
|
||||
if freq == "A" and not IS64 and isinstance(tz, tzlocal):
|
||||
request.node.add_marker(
|
||||
pytest.mark.xfail(reason="OverflowError inside tzlocal past 2038")
|
||||
)
|
||||
|
||||
idx = date_range(start="2013-04-01", periods=30, freq=freq, tz=tz)
|
||||
assert idx.resolution == expected
|
||||
|
||||
def test_infer_freq(self, freq_sample):
|
||||
# GH 11018
|
||||
idx = date_range("2011-01-01 09:00:00", freq=freq_sample, periods=10)
|
||||
result = DatetimeIndex(idx.asi8, freq="infer")
|
||||
tm.assert_index_equal(idx, result)
|
||||
assert result.freq == freq_sample
|
||||
|
||||
|
||||
@pytest.mark.parametrize("freq", ["B", "C"])
|
||||
class TestBusinessDatetimeIndex:
|
||||
@pytest.fixture
|
||||
def rng(self, freq):
|
||||
return bdate_range(START, END, freq=freq)
|
||||
|
||||
def test_comparison(self, rng):
|
||||
d = rng[10]
|
||||
|
||||
comp = rng > d
|
||||
assert comp[11]
|
||||
assert not comp[9]
|
||||
|
||||
def test_copy(self, rng):
|
||||
cp = rng.copy()
|
||||
repr(cp)
|
||||
tm.assert_index_equal(cp, rng)
|
||||
|
||||
def test_identical(self, rng):
|
||||
t1 = rng.copy()
|
||||
t2 = rng.copy()
|
||||
assert t1.identical(t2)
|
||||
|
||||
# name
|
||||
t1 = t1.rename("foo")
|
||||
assert t1.equals(t2)
|
||||
assert not t1.identical(t2)
|
||||
t2 = t2.rename("foo")
|
||||
assert t1.identical(t2)
|
||||
|
||||
# freq
|
||||
t2v = Index(t2.values)
|
||||
assert t1.equals(t2v)
|
||||
assert not t1.identical(t2v)
|
@ -0,0 +1,459 @@
|
||||
""" test partial slicing on Series/Frame """
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
import numpy as np
|
||||
import pytest
|
||||
|
||||
from pandas import (
|
||||
DataFrame,
|
||||
DatetimeIndex,
|
||||
Index,
|
||||
Series,
|
||||
Timedelta,
|
||||
Timestamp,
|
||||
date_range,
|
||||
)
|
||||
import pandas._testing as tm
|
||||
|
||||
|
||||
class TestSlicing:
|
||||
def test_string_index_series_name_converted(self):
|
||||
# GH#1644
|
||||
df = DataFrame(np.random.randn(10, 4), index=date_range("1/1/2000", periods=10))
|
||||
|
||||
result = df.loc["1/3/2000"]
|
||||
assert result.name == df.index[2]
|
||||
|
||||
result = df.T["1/3/2000"]
|
||||
assert result.name == df.index[2]
|
||||
|
||||
def test_stringified_slice_with_tz(self):
|
||||
# GH#2658
|
||||
start = "2013-01-07"
|
||||
idx = date_range(start=start, freq="1d", periods=10, tz="US/Eastern")
|
||||
df = DataFrame(np.arange(10), index=idx)
|
||||
df["2013-01-14 23:44:34.437768-05:00":] # no exception here
|
||||
|
||||
def test_return_type_doesnt_depend_on_monotonicity(self):
|
||||
# GH#24892 we get Series back regardless of whether our DTI is monotonic
|
||||
dti = date_range(start="2015-5-13 23:59:00", freq="min", periods=3)
|
||||
ser = Series(range(3), index=dti)
|
||||
|
||||
# non-monotonic index
|
||||
ser2 = Series(range(3), index=[dti[1], dti[0], dti[2]])
|
||||
|
||||
# key with resolution strictly lower than "min"
|
||||
key = "2015-5-14 00"
|
||||
|
||||
# monotonic increasing index
|
||||
result = ser.loc[key]
|
||||
expected = ser.iloc[1:]
|
||||
tm.assert_series_equal(result, expected)
|
||||
|
||||
# monotonic decreasing index
|
||||
result = ser.iloc[::-1].loc[key]
|
||||
expected = ser.iloc[::-1][:-1]
|
||||
tm.assert_series_equal(result, expected)
|
||||
|
||||
# non-monotonic index
|
||||
result2 = ser2.loc[key]
|
||||
expected2 = ser2.iloc[::2]
|
||||
tm.assert_series_equal(result2, expected2)
|
||||
|
||||
def test_return_type_doesnt_depend_on_monotonicity_higher_reso(self):
|
||||
# GH#24892 we get Series back regardless of whether our DTI is monotonic
|
||||
dti = date_range(start="2015-5-13 23:59:00", freq="min", periods=3)
|
||||
ser = Series(range(3), index=dti)
|
||||
|
||||
# non-monotonic index
|
||||
ser2 = Series(range(3), index=[dti[1], dti[0], dti[2]])
|
||||
|
||||
# key with resolution strictly *higher) than "min"
|
||||
key = "2015-5-14 00:00:00"
|
||||
|
||||
# monotonic increasing index
|
||||
result = ser.loc[key]
|
||||
assert result == 1
|
||||
|
||||
# monotonic decreasing index
|
||||
result = ser.iloc[::-1].loc[key]
|
||||
assert result == 1
|
||||
|
||||
# non-monotonic index
|
||||
result2 = ser2.loc[key]
|
||||
assert result2 == 0
|
||||
|
||||
def test_monotone_DTI_indexing_bug(self):
|
||||
# GH 19362
|
||||
# Testing accessing the first element in a monotonic descending
|
||||
# partial string indexing.
|
||||
|
||||
df = DataFrame(list(range(5)))
|
||||
date_list = [
|
||||
"2018-01-02",
|
||||
"2017-02-10",
|
||||
"2016-03-10",
|
||||
"2015-03-15",
|
||||
"2014-03-16",
|
||||
]
|
||||
date_index = DatetimeIndex(date_list)
|
||||
df["date"] = date_index
|
||||
expected = DataFrame({0: list(range(5)), "date": date_index})
|
||||
tm.assert_frame_equal(df, expected)
|
||||
|
||||
# We get a slice because df.index's resolution is hourly and we
|
||||
# are slicing with a daily-resolution string. If both were daily,
|
||||
# we would get a single item back
|
||||
dti = date_range("20170101 01:00:00", periods=3)
|
||||
df = DataFrame({"A": [1, 2, 3]}, index=dti[::-1])
|
||||
|
||||
expected = DataFrame({"A": 1}, index=dti[-1:][::-1])
|
||||
result = df.loc["2017-01-03"]
|
||||
tm.assert_frame_equal(result, expected)
|
||||
|
||||
result2 = df.iloc[::-1].loc["2017-01-03"]
|
||||
expected2 = expected.iloc[::-1]
|
||||
tm.assert_frame_equal(result2, expected2)
|
||||
|
||||
def test_slice_year(self):
|
||||
dti = date_range(freq="B", start=datetime(2005, 1, 1), periods=500)
|
||||
|
||||
s = Series(np.arange(len(dti)), index=dti)
|
||||
result = s["2005"]
|
||||
expected = s[s.index.year == 2005]
|
||||
tm.assert_series_equal(result, expected)
|
||||
|
||||
df = DataFrame(np.random.rand(len(dti), 5), index=dti)
|
||||
result = df.loc["2005"]
|
||||
expected = df[df.index.year == 2005]
|
||||
tm.assert_frame_equal(result, expected)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"partial_dtime",
|
||||
[
|
||||
"2019",
|
||||
"2019Q4",
|
||||
"Dec 2019",
|
||||
"2019-12-31",
|
||||
"2019-12-31 23",
|
||||
"2019-12-31 23:59",
|
||||
],
|
||||
)
|
||||
def test_slice_end_of_period_resolution(self, partial_dtime):
|
||||
# GH#31064
|
||||
dti = date_range("2019-12-31 23:59:55.999999999", periods=10, freq="s")
|
||||
|
||||
ser = Series(range(10), index=dti)
|
||||
result = ser[partial_dtime]
|
||||
expected = ser.iloc[:5]
|
||||
tm.assert_series_equal(result, expected)
|
||||
|
||||
def test_slice_quarter(self):
|
||||
dti = date_range(freq="D", start=datetime(2000, 6, 1), periods=500)
|
||||
|
||||
s = Series(np.arange(len(dti)), index=dti)
|
||||
assert len(s["2001Q1"]) == 90
|
||||
|
||||
df = DataFrame(np.random.rand(len(dti), 5), index=dti)
|
||||
assert len(df.loc["1Q01"]) == 90
|
||||
|
||||
def test_slice_month(self):
|
||||
dti = date_range(freq="D", start=datetime(2005, 1, 1), periods=500)
|
||||
s = Series(np.arange(len(dti)), index=dti)
|
||||
assert len(s["2005-11"]) == 30
|
||||
|
||||
df = DataFrame(np.random.rand(len(dti), 5), index=dti)
|
||||
assert len(df.loc["2005-11"]) == 30
|
||||
|
||||
tm.assert_series_equal(s["2005-11"], s["11-2005"])
|
||||
|
||||
def test_partial_slice(self):
|
||||
rng = date_range(freq="D", start=datetime(2005, 1, 1), periods=500)
|
||||
s = Series(np.arange(len(rng)), index=rng)
|
||||
|
||||
result = s["2005-05":"2006-02"]
|
||||
expected = s["20050501":"20060228"]
|
||||
tm.assert_series_equal(result, expected)
|
||||
|
||||
result = s["2005-05":]
|
||||
expected = s["20050501":]
|
||||
tm.assert_series_equal(result, expected)
|
||||
|
||||
result = s[:"2006-02"]
|
||||
expected = s[:"20060228"]
|
||||
tm.assert_series_equal(result, expected)
|
||||
|
||||
result = s["2005-1-1"]
|
||||
assert result == s.iloc[0]
|
||||
|
||||
with pytest.raises(KeyError, match=r"^'2004-12-31'$"):
|
||||
s["2004-12-31"]
|
||||
|
||||
def test_partial_slice_daily(self):
|
||||
rng = date_range(freq="H", start=datetime(2005, 1, 31), periods=500)
|
||||
s = Series(np.arange(len(rng)), index=rng)
|
||||
|
||||
result = s["2005-1-31"]
|
||||
tm.assert_series_equal(result, s.iloc[:24])
|
||||
|
||||
with pytest.raises(KeyError, match=r"^'2004-12-31 00'$"):
|
||||
s["2004-12-31 00"]
|
||||
|
||||
def test_partial_slice_hourly(self):
|
||||
rng = date_range(freq="T", start=datetime(2005, 1, 1, 20, 0, 0), periods=500)
|
||||
s = Series(np.arange(len(rng)), index=rng)
|
||||
|
||||
result = s["2005-1-1"]
|
||||
tm.assert_series_equal(result, s.iloc[: 60 * 4])
|
||||
|
||||
result = s["2005-1-1 20"]
|
||||
tm.assert_series_equal(result, s.iloc[:60])
|
||||
|
||||
assert s["2005-1-1 20:00"] == s.iloc[0]
|
||||
with pytest.raises(KeyError, match=r"^'2004-12-31 00:15'$"):
|
||||
s["2004-12-31 00:15"]
|
||||
|
||||
def test_partial_slice_minutely(self):
|
||||
rng = date_range(freq="S", start=datetime(2005, 1, 1, 23, 59, 0), periods=500)
|
||||
s = Series(np.arange(len(rng)), index=rng)
|
||||
|
||||
result = s["2005-1-1 23:59"]
|
||||
tm.assert_series_equal(result, s.iloc[:60])
|
||||
|
||||
result = s["2005-1-1"]
|
||||
tm.assert_series_equal(result, s.iloc[:60])
|
||||
|
||||
assert s[Timestamp("2005-1-1 23:59:00")] == s.iloc[0]
|
||||
with pytest.raises(KeyError, match=r"^'2004-12-31 00:00:00'$"):
|
||||
s["2004-12-31 00:00:00"]
|
||||
|
||||
def test_partial_slice_second_precision(self):
|
||||
rng = date_range(
|
||||
start=datetime(2005, 1, 1, 0, 0, 59, microsecond=999990),
|
||||
periods=20,
|
||||
freq="US",
|
||||
)
|
||||
s = Series(np.arange(20), rng)
|
||||
|
||||
tm.assert_series_equal(s["2005-1-1 00:00"], s.iloc[:10])
|
||||
tm.assert_series_equal(s["2005-1-1 00:00:59"], s.iloc[:10])
|
||||
|
||||
tm.assert_series_equal(s["2005-1-1 00:01"], s.iloc[10:])
|
||||
tm.assert_series_equal(s["2005-1-1 00:01:00"], s.iloc[10:])
|
||||
|
||||
assert s[Timestamp("2005-1-1 00:00:59.999990")] == s.iloc[0]
|
||||
with pytest.raises(KeyError, match="2005-1-1 00:00:00"):
|
||||
s["2005-1-1 00:00:00"]
|
||||
|
||||
def test_partial_slicing_dataframe(self):
|
||||
# GH14856
|
||||
# Test various combinations of string slicing resolution vs.
|
||||
# index resolution
|
||||
# - If string resolution is less precise than index resolution,
|
||||
# string is considered a slice
|
||||
# - If string resolution is equal to or more precise than index
|
||||
# resolution, string is considered an exact match
|
||||
formats = [
|
||||
"%Y",
|
||||
"%Y-%m",
|
||||
"%Y-%m-%d",
|
||||
"%Y-%m-%d %H",
|
||||
"%Y-%m-%d %H:%M",
|
||||
"%Y-%m-%d %H:%M:%S",
|
||||
]
|
||||
resolutions = ["year", "month", "day", "hour", "minute", "second"]
|
||||
for rnum, resolution in enumerate(resolutions[2:], 2):
|
||||
# we check only 'day', 'hour', 'minute' and 'second'
|
||||
unit = Timedelta("1 " + resolution)
|
||||
middate = datetime(2012, 1, 1, 0, 0, 0)
|
||||
index = DatetimeIndex([middate - unit, middate, middate + unit])
|
||||
values = [1, 2, 3]
|
||||
df = DataFrame({"a": values}, index, dtype=np.int64)
|
||||
assert df.index.resolution == resolution
|
||||
|
||||
# Timestamp with the same resolution as index
|
||||
# Should be exact match for Series (return scalar)
|
||||
# and raise KeyError for Frame
|
||||
for timestamp, expected in zip(index, values):
|
||||
ts_string = timestamp.strftime(formats[rnum])
|
||||
# make ts_string as precise as index
|
||||
result = df["a"][ts_string]
|
||||
assert isinstance(result, np.int64)
|
||||
assert result == expected
|
||||
msg = rf"^'{ts_string}'$"
|
||||
with pytest.raises(KeyError, match=msg):
|
||||
df[ts_string]
|
||||
|
||||
# Timestamp with resolution less precise than index
|
||||
for fmt in formats[:rnum]:
|
||||
for element, theslice in [[0, slice(None, 1)], [1, slice(1, None)]]:
|
||||
ts_string = index[element].strftime(fmt)
|
||||
|
||||
# Series should return slice
|
||||
result = df["a"][ts_string]
|
||||
expected = df["a"][theslice]
|
||||
tm.assert_series_equal(result, expected)
|
||||
|
||||
# Frame should return slice as well
|
||||
with tm.assert_produces_warning(FutureWarning):
|
||||
# GH#36179 deprecated this indexing
|
||||
result = df[ts_string]
|
||||
expected = df[theslice]
|
||||
tm.assert_frame_equal(result, expected)
|
||||
|
||||
# Timestamp with resolution more precise than index
|
||||
# Compatible with existing key
|
||||
# Should return scalar for Series
|
||||
# and raise KeyError for Frame
|
||||
for fmt in formats[rnum + 1 :]:
|
||||
ts_string = index[1].strftime(fmt)
|
||||
result = df["a"][ts_string]
|
||||
assert isinstance(result, np.int64)
|
||||
assert result == 2
|
||||
msg = rf"^'{ts_string}'$"
|
||||
with pytest.raises(KeyError, match=msg):
|
||||
df[ts_string]
|
||||
|
||||
# Not compatible with existing key
|
||||
# Should raise KeyError
|
||||
for fmt, res in list(zip(formats, resolutions))[rnum + 1 :]:
|
||||
ts = index[1] + Timedelta("1 " + res)
|
||||
ts_string = ts.strftime(fmt)
|
||||
msg = rf"^'{ts_string}'$"
|
||||
with pytest.raises(KeyError, match=msg):
|
||||
df["a"][ts_string]
|
||||
with pytest.raises(KeyError, match=msg):
|
||||
df[ts_string]
|
||||
|
||||
def test_partial_slicing_with_multiindex(self):
|
||||
|
||||
# GH 4758
|
||||
# partial string indexing with a multi-index buggy
|
||||
df = DataFrame(
|
||||
{
|
||||
"ACCOUNT": ["ACCT1", "ACCT1", "ACCT1", "ACCT2"],
|
||||
"TICKER": ["ABC", "MNP", "XYZ", "XYZ"],
|
||||
"val": [1, 2, 3, 4],
|
||||
},
|
||||
index=date_range("2013-06-19 09:30:00", periods=4, freq="5T"),
|
||||
)
|
||||
df_multi = df.set_index(["ACCOUNT", "TICKER"], append=True)
|
||||
|
||||
expected = DataFrame(
|
||||
[[1]], index=Index(["ABC"], name="TICKER"), columns=["val"]
|
||||
)
|
||||
result = df_multi.loc[("2013-06-19 09:30:00", "ACCT1")]
|
||||
tm.assert_frame_equal(result, expected)
|
||||
|
||||
expected = df_multi.loc[
|
||||
(Timestamp("2013-06-19 09:30:00", tz=None), "ACCT1", "ABC")
|
||||
]
|
||||
result = df_multi.loc[("2013-06-19 09:30:00", "ACCT1", "ABC")]
|
||||
tm.assert_series_equal(result, expected)
|
||||
|
||||
# partial string indexing on first level, scalar indexing on the other two
|
||||
result = df_multi.loc[("2013-06-19", "ACCT1", "ABC")]
|
||||
expected = df_multi.iloc[:1].droplevel([1, 2])
|
||||
tm.assert_frame_equal(result, expected)
|
||||
|
||||
def test_partial_slicing_with_multiindex_series(self):
|
||||
# GH 4294
|
||||
# partial slice on a series mi
|
||||
ser = DataFrame(
|
||||
np.random.rand(1000, 1000), index=date_range("2000-1-1", periods=1000)
|
||||
).stack()
|
||||
|
||||
s2 = ser[:-1].copy()
|
||||
expected = s2["2000-1-4"]
|
||||
result = s2[Timestamp("2000-1-4")]
|
||||
tm.assert_series_equal(result, expected)
|
||||
|
||||
result = ser[Timestamp("2000-1-4")]
|
||||
expected = ser["2000-1-4"]
|
||||
tm.assert_series_equal(result, expected)
|
||||
|
||||
df2 = DataFrame(ser)
|
||||
expected = df2.xs("2000-1-4")
|
||||
result = df2.loc[Timestamp("2000-1-4")]
|
||||
tm.assert_frame_equal(result, expected)
|
||||
|
||||
def test_partial_slice_doesnt_require_monotonicity(self):
|
||||
# For historical reasons.
|
||||
ser = Series(np.arange(10), date_range("2014-01-01", periods=10))
|
||||
|
||||
nonmonotonic = ser[[3, 5, 4]]
|
||||
expected = nonmonotonic.iloc[:0]
|
||||
timestamp = Timestamp("2014-01-10")
|
||||
with tm.assert_produces_warning(FutureWarning):
|
||||
result = nonmonotonic["2014-01-10":]
|
||||
tm.assert_series_equal(result, expected)
|
||||
|
||||
with pytest.raises(KeyError, match=r"Timestamp\('2014-01-10 00:00:00'\)"):
|
||||
nonmonotonic[timestamp:]
|
||||
|
||||
with tm.assert_produces_warning(FutureWarning):
|
||||
result = nonmonotonic.loc["2014-01-10":]
|
||||
tm.assert_series_equal(result, expected)
|
||||
|
||||
with pytest.raises(KeyError, match=r"Timestamp\('2014-01-10 00:00:00'\)"):
|
||||
nonmonotonic.loc[timestamp:]
|
||||
|
||||
def test_loc_datetime_length_one(self):
|
||||
# GH16071
|
||||
df = DataFrame(
|
||||
columns=["1"],
|
||||
index=date_range("2016-10-01T00:00:00", "2016-10-01T23:59:59"),
|
||||
)
|
||||
result = df.loc[datetime(2016, 10, 1) :]
|
||||
tm.assert_frame_equal(result, df)
|
||||
|
||||
result = df.loc["2016-10-01T00:00:00":]
|
||||
tm.assert_frame_equal(result, df)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"start",
|
||||
[
|
||||
"2018-12-02 21:50:00+00:00",
|
||||
Timestamp("2018-12-02 21:50:00+00:00"),
|
||||
Timestamp("2018-12-02 21:50:00+00:00").to_pydatetime(),
|
||||
],
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
"end",
|
||||
[
|
||||
"2018-12-02 21:52:00+00:00",
|
||||
Timestamp("2018-12-02 21:52:00+00:00"),
|
||||
Timestamp("2018-12-02 21:52:00+00:00").to_pydatetime(),
|
||||
],
|
||||
)
|
||||
def test_getitem_with_datestring_with_UTC_offset(self, start, end):
|
||||
# GH 24076
|
||||
idx = date_range(
|
||||
start="2018-12-02 14:50:00-07:00",
|
||||
end="2018-12-02 14:50:00-07:00",
|
||||
freq="1min",
|
||||
)
|
||||
df = DataFrame(1, index=idx, columns=["A"])
|
||||
result = df[start:end]
|
||||
expected = df.iloc[0:3, :]
|
||||
tm.assert_frame_equal(result, expected)
|
||||
|
||||
# GH 16785
|
||||
start = str(start)
|
||||
end = str(end)
|
||||
with pytest.raises(ValueError, match="Both dates must"):
|
||||
df[start : end[:-4] + "1:00"]
|
||||
|
||||
with pytest.raises(ValueError, match="The index must be timezone"):
|
||||
df = df.tz_localize(None)
|
||||
df[start:end]
|
||||
|
||||
def test_slice_reduce_to_series(self):
|
||||
# GH 27516
|
||||
df = DataFrame({"A": range(24)}, index=date_range("2000", periods=24, freq="M"))
|
||||
expected = Series(
|
||||
range(12), index=date_range("2000", periods=12, freq="M"), name="A"
|
||||
)
|
||||
result = df.loc["2000", "A"]
|
||||
tm.assert_series_equal(result, expected)
|
@ -0,0 +1,45 @@
|
||||
import pytest
|
||||
|
||||
from pandas import (
|
||||
NaT,
|
||||
date_range,
|
||||
to_datetime,
|
||||
)
|
||||
import pandas._testing as tm
|
||||
|
||||
|
||||
class TestPickle:
|
||||
def test_pickle(self):
|
||||
# GH#4606
|
||||
idx = to_datetime(["2013-01-01", NaT, "2014-01-06"])
|
||||
idx_p = tm.round_trip_pickle(idx)
|
||||
assert idx_p[0] == idx[0]
|
||||
assert idx_p[1] is NaT
|
||||
assert idx_p[2] == idx[2]
|
||||
|
||||
def test_pickle_dont_infer_freq(self):
|
||||
# GH#11002
|
||||
# don't infer freq
|
||||
idx = date_range("1750-1-1", "2050-1-1", freq="7D")
|
||||
idx_p = tm.round_trip_pickle(idx)
|
||||
tm.assert_index_equal(idx, idx_p)
|
||||
|
||||
def test_pickle_after_set_freq(self):
|
||||
dti = date_range("20130101", periods=3, tz="US/Eastern", name="foo")
|
||||
dti = dti._with_freq(None)
|
||||
|
||||
res = tm.round_trip_pickle(dti)
|
||||
tm.assert_index_equal(res, dti)
|
||||
|
||||
def test_roundtrip_pickle_with_tz(self):
|
||||
# GH#8367
|
||||
# round-trip of timezone
|
||||
index = date_range("20130101", periods=3, tz="US/Eastern", name="foo")
|
||||
unpickled = tm.round_trip_pickle(index)
|
||||
tm.assert_index_equal(index, unpickled)
|
||||
|
||||
@pytest.mark.parametrize("freq", ["B", "C"])
|
||||
def test_pickle_unpickle(self, freq):
|
||||
rng = date_range("2009-01-01", "2010-01-01", freq=freq)
|
||||
unpickled = tm.round_trip_pickle(rng)
|
||||
assert unpickled.freq == freq
|
@ -0,0 +1,56 @@
|
||||
from datetime import timedelta
|
||||
|
||||
import numpy as np
|
||||
|
||||
from pandas import (
|
||||
DatetimeIndex,
|
||||
date_range,
|
||||
)
|
||||
import pandas._testing as tm
|
||||
|
||||
|
||||
class TestDatetimeIndexReindex:
|
||||
def test_reindex_preserves_tz_if_target_is_empty_list_or_array(self):
|
||||
# GH#7774
|
||||
index = date_range("2013-01-01", periods=3, tz="US/Eastern")
|
||||
assert str(index.reindex([])[0].tz) == "US/Eastern"
|
||||
assert str(index.reindex(np.array([]))[0].tz) == "US/Eastern"
|
||||
|
||||
def test_reindex_with_same_tz_nearest(self):
|
||||
# GH#32740
|
||||
rng_a = date_range("2010-01-01", "2010-01-02", periods=24, tz="utc")
|
||||
rng_b = date_range("2010-01-01", "2010-01-02", periods=23, tz="utc")
|
||||
result1, result2 = rng_a.reindex(
|
||||
rng_b, method="nearest", tolerance=timedelta(seconds=20)
|
||||
)
|
||||
expected_list1 = [
|
||||
"2010-01-01 00:00:00",
|
||||
"2010-01-01 01:05:27.272727272",
|
||||
"2010-01-01 02:10:54.545454545",
|
||||
"2010-01-01 03:16:21.818181818",
|
||||
"2010-01-01 04:21:49.090909090",
|
||||
"2010-01-01 05:27:16.363636363",
|
||||
"2010-01-01 06:32:43.636363636",
|
||||
"2010-01-01 07:38:10.909090909",
|
||||
"2010-01-01 08:43:38.181818181",
|
||||
"2010-01-01 09:49:05.454545454",
|
||||
"2010-01-01 10:54:32.727272727",
|
||||
"2010-01-01 12:00:00",
|
||||
"2010-01-01 13:05:27.272727272",
|
||||
"2010-01-01 14:10:54.545454545",
|
||||
"2010-01-01 15:16:21.818181818",
|
||||
"2010-01-01 16:21:49.090909090",
|
||||
"2010-01-01 17:27:16.363636363",
|
||||
"2010-01-01 18:32:43.636363636",
|
||||
"2010-01-01 19:38:10.909090909",
|
||||
"2010-01-01 20:43:38.181818181",
|
||||
"2010-01-01 21:49:05.454545454",
|
||||
"2010-01-01 22:54:32.727272727",
|
||||
"2010-01-02 00:00:00",
|
||||
]
|
||||
expected1 = DatetimeIndex(
|
||||
expected_list1, dtype="datetime64[ns, UTC]", freq=None
|
||||
)
|
||||
expected2 = np.array([0] + [-1] * 21 + [23], dtype=np.dtype("intp"))
|
||||
tm.assert_index_equal(result1, expected1)
|
||||
tm.assert_numpy_array_equal(result2, expected2)
|
@ -0,0 +1,363 @@
|
||||
"""
|
||||
Tests for DatetimeIndex methods behaving like their Timestamp counterparts
|
||||
"""
|
||||
from datetime import datetime
|
||||
|
||||
import numpy as np
|
||||
import pytest
|
||||
|
||||
from pandas._libs.tslibs import (
|
||||
OutOfBoundsDatetime,
|
||||
to_offset,
|
||||
)
|
||||
from pandas._libs.tslibs.offsets import INVALID_FREQ_ERR_MSG
|
||||
|
||||
import pandas as pd
|
||||
from pandas import (
|
||||
DatetimeIndex,
|
||||
Timestamp,
|
||||
date_range,
|
||||
)
|
||||
import pandas._testing as tm
|
||||
from pandas.core.api import Float64Index
|
||||
|
||||
|
||||
class TestDatetimeIndexOps:
|
||||
def test_dti_time(self):
|
||||
rng = date_range("1/1/2000", freq="12min", periods=10)
|
||||
result = pd.Index(rng).time
|
||||
expected = [t.time() for t in rng]
|
||||
assert (result == expected).all()
|
||||
|
||||
def test_dti_date(self):
|
||||
rng = date_range("1/1/2000", freq="12H", periods=10)
|
||||
result = pd.Index(rng).date
|
||||
expected = [t.date() for t in rng]
|
||||
assert (result == expected).all()
|
||||
|
||||
@pytest.mark.parametrize("data", [["1400-01-01"], [datetime(1400, 1, 1)]])
|
||||
def test_dti_date_out_of_range(self, data):
|
||||
# GH#1475
|
||||
msg = "Out of bounds nanosecond timestamp: 1400-01-01 00:00:00"
|
||||
with pytest.raises(OutOfBoundsDatetime, match=msg):
|
||||
DatetimeIndex(data)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"field",
|
||||
[
|
||||
"dayofweek",
|
||||
"day_of_week",
|
||||
"dayofyear",
|
||||
"day_of_year",
|
||||
"quarter",
|
||||
"days_in_month",
|
||||
"is_month_start",
|
||||
"is_month_end",
|
||||
"is_quarter_start",
|
||||
"is_quarter_end",
|
||||
"is_year_start",
|
||||
"is_year_end",
|
||||
],
|
||||
)
|
||||
def test_dti_timestamp_fields(self, field):
|
||||
# extra fields from DatetimeIndex like quarter and week
|
||||
idx = tm.makeDateIndex(100)
|
||||
expected = getattr(idx, field)[-1]
|
||||
|
||||
warn = FutureWarning if field.startswith("is_") else None
|
||||
with tm.assert_produces_warning(warn, match="Timestamp.freq is deprecated"):
|
||||
result = getattr(Timestamp(idx[-1]), field)
|
||||
assert result == expected
|
||||
|
||||
def test_dti_timestamp_isocalendar_fields(self):
|
||||
idx = tm.makeDateIndex(100)
|
||||
expected = tuple(idx.isocalendar().iloc[-1].to_list())
|
||||
result = idx[-1].isocalendar()
|
||||
assert result == expected
|
||||
|
||||
def test_dti_timestamp_freq_fields(self):
|
||||
# extra fields from DatetimeIndex like quarter and week
|
||||
idx = tm.makeDateIndex(100)
|
||||
|
||||
msg = "The 'freq' argument in Timestamp is deprecated"
|
||||
with tm.assert_produces_warning(FutureWarning, match=msg):
|
||||
ts = Timestamp(idx[-1], idx.freq)
|
||||
|
||||
msg2 = "Timestamp.freq is deprecated"
|
||||
with tm.assert_produces_warning(FutureWarning, match=msg2):
|
||||
assert idx.freq == ts.freq
|
||||
|
||||
msg3 = "Timestamp.freqstr is deprecated"
|
||||
with tm.assert_produces_warning(FutureWarning, match=msg3):
|
||||
assert idx.freqstr == ts.freqstr
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
# DatetimeIndex.round
|
||||
|
||||
def test_round_daily(self):
|
||||
dti = date_range("20130101 09:10:11", periods=5)
|
||||
result = dti.round("D")
|
||||
expected = date_range("20130101", periods=5)
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
dti = dti.tz_localize("UTC").tz_convert("US/Eastern")
|
||||
result = dti.round("D")
|
||||
expected = date_range("20130101", periods=5).tz_localize("US/Eastern")
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
result = dti.round("s")
|
||||
tm.assert_index_equal(result, dti)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"freq, error_msg",
|
||||
[
|
||||
("Y", "<YearEnd: month=12> is a non-fixed frequency"),
|
||||
("M", "<MonthEnd> is a non-fixed frequency"),
|
||||
("foobar", "Invalid frequency: foobar"),
|
||||
],
|
||||
)
|
||||
def test_round_invalid(self, freq, error_msg):
|
||||
dti = date_range("20130101 09:10:11", periods=5)
|
||||
dti = dti.tz_localize("UTC").tz_convert("US/Eastern")
|
||||
with pytest.raises(ValueError, match=error_msg):
|
||||
dti.round(freq)
|
||||
|
||||
def test_round(self, tz_naive_fixture):
|
||||
tz = tz_naive_fixture
|
||||
rng = date_range(start="2016-01-01", periods=5, freq="30Min", tz=tz)
|
||||
elt = rng[1]
|
||||
|
||||
expected_rng = DatetimeIndex(
|
||||
[
|
||||
Timestamp("2016-01-01 00:00:00", tz=tz),
|
||||
Timestamp("2016-01-01 00:00:00", tz=tz),
|
||||
Timestamp("2016-01-01 01:00:00", tz=tz),
|
||||
Timestamp("2016-01-01 02:00:00", tz=tz),
|
||||
Timestamp("2016-01-01 02:00:00", tz=tz),
|
||||
]
|
||||
)
|
||||
expected_elt = expected_rng[1]
|
||||
|
||||
tm.assert_index_equal(rng.round(freq="H"), expected_rng)
|
||||
assert elt.round(freq="H") == expected_elt
|
||||
|
||||
msg = INVALID_FREQ_ERR_MSG
|
||||
with pytest.raises(ValueError, match=msg):
|
||||
rng.round(freq="foo")
|
||||
with pytest.raises(ValueError, match=msg):
|
||||
elt.round(freq="foo")
|
||||
|
||||
msg = "<MonthEnd> is a non-fixed frequency"
|
||||
with pytest.raises(ValueError, match=msg):
|
||||
rng.round(freq="M")
|
||||
with pytest.raises(ValueError, match=msg):
|
||||
elt.round(freq="M")
|
||||
|
||||
# GH#14440 & GH#15578
|
||||
index = DatetimeIndex(["2016-10-17 12:00:00.0015"], tz=tz)
|
||||
result = index.round("ms")
|
||||
expected = DatetimeIndex(["2016-10-17 12:00:00.002000"], tz=tz)
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
for freq in ["us", "ns"]:
|
||||
tm.assert_index_equal(index, index.round(freq))
|
||||
|
||||
index = DatetimeIndex(["2016-10-17 12:00:00.00149"], tz=tz)
|
||||
result = index.round("ms")
|
||||
expected = DatetimeIndex(["2016-10-17 12:00:00.001000"], tz=tz)
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
index = DatetimeIndex(["2016-10-17 12:00:00.001501031"])
|
||||
result = index.round("10ns")
|
||||
expected = DatetimeIndex(["2016-10-17 12:00:00.001501030"])
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
with tm.assert_produces_warning(False):
|
||||
ts = "2016-10-17 12:00:00.001501031"
|
||||
DatetimeIndex([ts]).round("1010ns")
|
||||
|
||||
def test_no_rounding_occurs(self, tz_naive_fixture):
|
||||
# GH 21262
|
||||
tz = tz_naive_fixture
|
||||
rng = date_range(start="2016-01-01", periods=5, freq="2Min", tz=tz)
|
||||
|
||||
expected_rng = DatetimeIndex(
|
||||
[
|
||||
Timestamp("2016-01-01 00:00:00", tz=tz),
|
||||
Timestamp("2016-01-01 00:02:00", tz=tz),
|
||||
Timestamp("2016-01-01 00:04:00", tz=tz),
|
||||
Timestamp("2016-01-01 00:06:00", tz=tz),
|
||||
Timestamp("2016-01-01 00:08:00", tz=tz),
|
||||
]
|
||||
)
|
||||
|
||||
tm.assert_index_equal(rng.round(freq="2T"), expected_rng)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"test_input, rounder, freq, expected",
|
||||
[
|
||||
(["2117-01-01 00:00:45"], "floor", "15s", ["2117-01-01 00:00:45"]),
|
||||
(["2117-01-01 00:00:45"], "ceil", "15s", ["2117-01-01 00:00:45"]),
|
||||
(
|
||||
["2117-01-01 00:00:45.000000012"],
|
||||
"floor",
|
||||
"10ns",
|
||||
["2117-01-01 00:00:45.000000010"],
|
||||
),
|
||||
(
|
||||
["1823-01-01 00:00:01.000000012"],
|
||||
"ceil",
|
||||
"10ns",
|
||||
["1823-01-01 00:00:01.000000020"],
|
||||
),
|
||||
(["1823-01-01 00:00:01"], "floor", "1s", ["1823-01-01 00:00:01"]),
|
||||
(["1823-01-01 00:00:01"], "ceil", "1s", ["1823-01-01 00:00:01"]),
|
||||
(["2018-01-01 00:15:00"], "ceil", "15T", ["2018-01-01 00:15:00"]),
|
||||
(["2018-01-01 00:15:00"], "floor", "15T", ["2018-01-01 00:15:00"]),
|
||||
(["1823-01-01 03:00:00"], "ceil", "3H", ["1823-01-01 03:00:00"]),
|
||||
(["1823-01-01 03:00:00"], "floor", "3H", ["1823-01-01 03:00:00"]),
|
||||
(
|
||||
("NaT", "1823-01-01 00:00:01"),
|
||||
"floor",
|
||||
"1s",
|
||||
("NaT", "1823-01-01 00:00:01"),
|
||||
),
|
||||
(
|
||||
("NaT", "1823-01-01 00:00:01"),
|
||||
"ceil",
|
||||
"1s",
|
||||
("NaT", "1823-01-01 00:00:01"),
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_ceil_floor_edge(self, test_input, rounder, freq, expected):
|
||||
dt = DatetimeIndex(list(test_input))
|
||||
func = getattr(dt, rounder)
|
||||
result = func(freq)
|
||||
expected = DatetimeIndex(list(expected))
|
||||
assert expected.equals(result)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"start, index_freq, periods",
|
||||
[("2018-01-01", "12H", 25), ("2018-01-01 0:0:0.124999", "1ns", 1000)],
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
"round_freq",
|
||||
[
|
||||
"2ns",
|
||||
"3ns",
|
||||
"4ns",
|
||||
"5ns",
|
||||
"6ns",
|
||||
"7ns",
|
||||
"250ns",
|
||||
"500ns",
|
||||
"750ns",
|
||||
"1us",
|
||||
"19us",
|
||||
"250us",
|
||||
"500us",
|
||||
"750us",
|
||||
"1s",
|
||||
"2s",
|
||||
"3s",
|
||||
"12H",
|
||||
"1D",
|
||||
],
|
||||
)
|
||||
def test_round_int64(self, start, index_freq, periods, round_freq):
|
||||
dt = date_range(start=start, freq=index_freq, periods=periods)
|
||||
unit = to_offset(round_freq).nanos
|
||||
|
||||
# test floor
|
||||
result = dt.floor(round_freq)
|
||||
diff = dt.asi8 - result.asi8
|
||||
mod = result.asi8 % unit
|
||||
assert (mod == 0).all(), f"floor not a {round_freq} multiple"
|
||||
assert (0 <= diff).all() and (diff < unit).all(), "floor error"
|
||||
|
||||
# test ceil
|
||||
result = dt.ceil(round_freq)
|
||||
diff = result.asi8 - dt.asi8
|
||||
mod = result.asi8 % unit
|
||||
assert (mod == 0).all(), f"ceil not a {round_freq} multiple"
|
||||
assert (0 <= diff).all() and (diff < unit).all(), "ceil error"
|
||||
|
||||
# test round
|
||||
result = dt.round(round_freq)
|
||||
diff = abs(result.asi8 - dt.asi8)
|
||||
mod = result.asi8 % unit
|
||||
assert (mod == 0).all(), f"round not a {round_freq} multiple"
|
||||
assert (diff <= unit // 2).all(), "round error"
|
||||
if unit % 2 == 0:
|
||||
assert (
|
||||
result.asi8[diff == unit // 2] % 2 == 0
|
||||
).all(), "round half to even error"
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
# DatetimeIndex.normalize
|
||||
|
||||
def test_normalize(self):
|
||||
rng = date_range("1/1/2000 9:30", periods=10, freq="D")
|
||||
|
||||
result = rng.normalize()
|
||||
expected = date_range("1/1/2000", periods=10, freq="D")
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
arr_ns = np.array([1380585623454345752, 1380585612343234312]).astype(
|
||||
"datetime64[ns]"
|
||||
)
|
||||
rng_ns = DatetimeIndex(arr_ns)
|
||||
rng_ns_normalized = rng_ns.normalize()
|
||||
|
||||
arr_ns = np.array([1380585600000000000, 1380585600000000000]).astype(
|
||||
"datetime64[ns]"
|
||||
)
|
||||
expected = DatetimeIndex(arr_ns)
|
||||
tm.assert_index_equal(rng_ns_normalized, expected)
|
||||
|
||||
assert result.is_normalized
|
||||
assert not rng.is_normalized
|
||||
|
||||
def test_normalize_nat(self):
|
||||
dti = DatetimeIndex([pd.NaT, Timestamp("2018-01-01 01:00:00")])
|
||||
result = dti.normalize()
|
||||
expected = DatetimeIndex([pd.NaT, Timestamp("2018-01-01")])
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
|
||||
class TestDateTimeIndexToJulianDate:
|
||||
def test_1700(self):
|
||||
dr = date_range(start=Timestamp("1710-10-01"), periods=5, freq="D")
|
||||
r1 = pd.Index([x.to_julian_date() for x in dr])
|
||||
r2 = dr.to_julian_date()
|
||||
assert isinstance(r2, Float64Index)
|
||||
tm.assert_index_equal(r1, r2)
|
||||
|
||||
def test_2000(self):
|
||||
dr = date_range(start=Timestamp("2000-02-27"), periods=5, freq="D")
|
||||
r1 = pd.Index([x.to_julian_date() for x in dr])
|
||||
r2 = dr.to_julian_date()
|
||||
assert isinstance(r2, Float64Index)
|
||||
tm.assert_index_equal(r1, r2)
|
||||
|
||||
def test_hour(self):
|
||||
dr = date_range(start=Timestamp("2000-02-27"), periods=5, freq="H")
|
||||
r1 = pd.Index([x.to_julian_date() for x in dr])
|
||||
r2 = dr.to_julian_date()
|
||||
assert isinstance(r2, Float64Index)
|
||||
tm.assert_index_equal(r1, r2)
|
||||
|
||||
def test_minute(self):
|
||||
dr = date_range(start=Timestamp("2000-02-27"), periods=5, freq="T")
|
||||
r1 = pd.Index([x.to_julian_date() for x in dr])
|
||||
r2 = dr.to_julian_date()
|
||||
assert isinstance(r2, Float64Index)
|
||||
tm.assert_index_equal(r1, r2)
|
||||
|
||||
def test_second(self):
|
||||
dr = date_range(start=Timestamp("2000-02-27"), periods=5, freq="S")
|
||||
r1 = pd.Index([x.to_julian_date() for x in dr])
|
||||
r2 = dr.to_julian_date()
|
||||
assert isinstance(r2, Float64Index)
|
||||
tm.assert_index_equal(r1, r2)
|
@ -0,0 +1,599 @@
|
||||
from datetime import datetime
|
||||
|
||||
import numpy as np
|
||||
import pytest
|
||||
|
||||
import pandas.util._test_decorators as td
|
||||
|
||||
import pandas as pd
|
||||
from pandas import (
|
||||
DataFrame,
|
||||
DatetimeIndex,
|
||||
Index,
|
||||
Series,
|
||||
bdate_range,
|
||||
date_range,
|
||||
)
|
||||
import pandas._testing as tm
|
||||
from pandas.core.api import Int64Index
|
||||
|
||||
from pandas.tseries.offsets import (
|
||||
BMonthEnd,
|
||||
Minute,
|
||||
MonthEnd,
|
||||
)
|
||||
|
||||
START, END = datetime(2009, 1, 1), datetime(2010, 1, 1)
|
||||
|
||||
|
||||
def test_union_many_deprecated():
|
||||
dti = date_range("2016-01-01", periods=3)
|
||||
|
||||
with tm.assert_produces_warning(FutureWarning):
|
||||
dti.union_many([dti, dti])
|
||||
|
||||
|
||||
class TestDatetimeIndexSetOps:
|
||||
tz = [
|
||||
None,
|
||||
"UTC",
|
||||
"Asia/Tokyo",
|
||||
"US/Eastern",
|
||||
"dateutil/Asia/Singapore",
|
||||
"dateutil/US/Pacific",
|
||||
]
|
||||
|
||||
# TODO: moved from test_datetimelike; dedup with version below
|
||||
def test_union2(self, sort):
|
||||
everything = tm.makeDateIndex(10)
|
||||
first = everything[:5]
|
||||
second = everything[5:]
|
||||
union = first.union(second, sort=sort)
|
||||
tm.assert_index_equal(union, everything)
|
||||
|
||||
@pytest.mark.parametrize("box", [np.array, Series, list])
|
||||
def test_union3(self, sort, box):
|
||||
everything = tm.makeDateIndex(10)
|
||||
first = everything[:5]
|
||||
second = everything[5:]
|
||||
|
||||
# GH 10149 support listlike inputs other than Index objects
|
||||
expected = first.union(second, sort=sort)
|
||||
case = box(second.values)
|
||||
result = first.union(case, sort=sort)
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
@pytest.mark.parametrize("tz", tz)
|
||||
def test_union(self, tz, sort):
|
||||
rng1 = date_range("1/1/2000", freq="D", periods=5, tz=tz)
|
||||
other1 = date_range("1/6/2000", freq="D", periods=5, tz=tz)
|
||||
expected1 = date_range("1/1/2000", freq="D", periods=10, tz=tz)
|
||||
expected1_notsorted = DatetimeIndex(list(other1) + list(rng1))
|
||||
|
||||
rng2 = date_range("1/1/2000", freq="D", periods=5, tz=tz)
|
||||
other2 = date_range("1/4/2000", freq="D", periods=5, tz=tz)
|
||||
expected2 = date_range("1/1/2000", freq="D", periods=8, tz=tz)
|
||||
expected2_notsorted = DatetimeIndex(list(other2) + list(rng2[:3]))
|
||||
|
||||
rng3 = date_range("1/1/2000", freq="D", periods=5, tz=tz)
|
||||
other3 = DatetimeIndex([], tz=tz)
|
||||
expected3 = date_range("1/1/2000", freq="D", periods=5, tz=tz)
|
||||
expected3_notsorted = rng3
|
||||
|
||||
for rng, other, exp, exp_notsorted in [
|
||||
(rng1, other1, expected1, expected1_notsorted),
|
||||
(rng2, other2, expected2, expected2_notsorted),
|
||||
(rng3, other3, expected3, expected3_notsorted),
|
||||
]:
|
||||
|
||||
result_union = rng.union(other, sort=sort)
|
||||
tm.assert_index_equal(result_union, exp)
|
||||
|
||||
result_union = other.union(rng, sort=sort)
|
||||
if sort is None:
|
||||
tm.assert_index_equal(result_union, exp)
|
||||
else:
|
||||
tm.assert_index_equal(result_union, exp_notsorted)
|
||||
|
||||
def test_union_coverage(self, sort):
|
||||
idx = DatetimeIndex(["2000-01-03", "2000-01-01", "2000-01-02"])
|
||||
ordered = DatetimeIndex(idx.sort_values(), freq="infer")
|
||||
result = ordered.union(idx, sort=sort)
|
||||
tm.assert_index_equal(result, ordered)
|
||||
|
||||
result = ordered[:0].union(ordered, sort=sort)
|
||||
tm.assert_index_equal(result, ordered)
|
||||
assert result.freq == ordered.freq
|
||||
|
||||
def test_union_bug_1730(self, sort):
|
||||
rng_a = date_range("1/1/2012", periods=4, freq="3H")
|
||||
rng_b = date_range("1/1/2012", periods=4, freq="4H")
|
||||
|
||||
result = rng_a.union(rng_b, sort=sort)
|
||||
exp = list(rng_a) + list(rng_b[1:])
|
||||
if sort is None:
|
||||
exp = DatetimeIndex(sorted(exp))
|
||||
else:
|
||||
exp = DatetimeIndex(exp)
|
||||
tm.assert_index_equal(result, exp)
|
||||
|
||||
def test_union_bug_1745(self, sort):
|
||||
left = DatetimeIndex(["2012-05-11 15:19:49.695000"])
|
||||
right = DatetimeIndex(
|
||||
[
|
||||
"2012-05-29 13:04:21.322000",
|
||||
"2012-05-11 15:27:24.873000",
|
||||
"2012-05-11 15:31:05.350000",
|
||||
]
|
||||
)
|
||||
|
||||
result = left.union(right, sort=sort)
|
||||
exp = DatetimeIndex(
|
||||
[
|
||||
"2012-05-11 15:19:49.695000",
|
||||
"2012-05-29 13:04:21.322000",
|
||||
"2012-05-11 15:27:24.873000",
|
||||
"2012-05-11 15:31:05.350000",
|
||||
]
|
||||
)
|
||||
if sort is None:
|
||||
exp = exp.sort_values()
|
||||
tm.assert_index_equal(result, exp)
|
||||
|
||||
def test_union_bug_4564(self, sort):
|
||||
from pandas import DateOffset
|
||||
|
||||
left = date_range("2013-01-01", "2013-02-01")
|
||||
right = left + DateOffset(minutes=15)
|
||||
|
||||
result = left.union(right, sort=sort)
|
||||
exp = list(left) + list(right)
|
||||
if sort is None:
|
||||
exp = DatetimeIndex(sorted(exp))
|
||||
else:
|
||||
exp = DatetimeIndex(exp)
|
||||
tm.assert_index_equal(result, exp)
|
||||
|
||||
def test_union_freq_both_none(self, sort):
|
||||
# GH11086
|
||||
expected = bdate_range("20150101", periods=10)
|
||||
expected._data.freq = None
|
||||
|
||||
result = expected.union(expected, sort=sort)
|
||||
tm.assert_index_equal(result, expected)
|
||||
assert result.freq is None
|
||||
|
||||
def test_union_freq_infer(self):
|
||||
# When taking the union of two DatetimeIndexes, we infer
|
||||
# a freq even if the arguments don't have freq. This matches
|
||||
# TimedeltaIndex behavior.
|
||||
dti = date_range("2016-01-01", periods=5)
|
||||
left = dti[[0, 1, 3, 4]]
|
||||
right = dti[[2, 3, 1]]
|
||||
|
||||
assert left.freq is None
|
||||
assert right.freq is None
|
||||
|
||||
result = left.union(right)
|
||||
tm.assert_index_equal(result, dti)
|
||||
assert result.freq == "D"
|
||||
|
||||
def test_union_dataframe_index(self):
|
||||
rng1 = date_range("1/1/1999", "1/1/2012", freq="MS")
|
||||
s1 = Series(np.random.randn(len(rng1)), rng1)
|
||||
|
||||
rng2 = date_range("1/1/1980", "12/1/2001", freq="MS")
|
||||
s2 = Series(np.random.randn(len(rng2)), rng2)
|
||||
df = DataFrame({"s1": s1, "s2": s2})
|
||||
|
||||
exp = date_range("1/1/1980", "1/1/2012", freq="MS")
|
||||
tm.assert_index_equal(df.index, exp)
|
||||
|
||||
def test_union_with_DatetimeIndex(self, sort):
|
||||
i1 = Int64Index(np.arange(0, 20, 2))
|
||||
i2 = date_range(start="2012-01-03 00:00:00", periods=10, freq="D")
|
||||
# Works
|
||||
i1.union(i2, sort=sort)
|
||||
# Fails with "AttributeError: can't set attribute"
|
||||
i2.union(i1, sort=sort)
|
||||
|
||||
# TODO: moved from test_datetimelike; de-duplicate with version below
|
||||
def test_intersection2(self):
|
||||
first = tm.makeDateIndex(10)
|
||||
second = first[5:]
|
||||
intersect = first.intersection(second)
|
||||
assert tm.equalContents(intersect, second)
|
||||
|
||||
# GH 10149
|
||||
cases = [klass(second.values) for klass in [np.array, Series, list]]
|
||||
for case in cases:
|
||||
result = first.intersection(case)
|
||||
assert tm.equalContents(result, second)
|
||||
|
||||
third = Index(["a", "b", "c"])
|
||||
result = first.intersection(third)
|
||||
expected = Index([], dtype=object)
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"tz", [None, "Asia/Tokyo", "US/Eastern", "dateutil/US/Pacific"]
|
||||
)
|
||||
def test_intersection(self, tz, sort):
|
||||
# GH 4690 (with tz)
|
||||
base = date_range("6/1/2000", "6/30/2000", freq="D", name="idx")
|
||||
|
||||
# if target has the same name, it is preserved
|
||||
rng2 = date_range("5/15/2000", "6/20/2000", freq="D", name="idx")
|
||||
expected2 = date_range("6/1/2000", "6/20/2000", freq="D", name="idx")
|
||||
|
||||
# if target name is different, it will be reset
|
||||
rng3 = date_range("5/15/2000", "6/20/2000", freq="D", name="other")
|
||||
expected3 = date_range("6/1/2000", "6/20/2000", freq="D", name=None)
|
||||
|
||||
rng4 = date_range("7/1/2000", "7/31/2000", freq="D", name="idx")
|
||||
expected4 = DatetimeIndex([], freq="D", name="idx")
|
||||
|
||||
for (rng, expected) in [
|
||||
(rng2, expected2),
|
||||
(rng3, expected3),
|
||||
(rng4, expected4),
|
||||
]:
|
||||
result = base.intersection(rng)
|
||||
tm.assert_index_equal(result, expected)
|
||||
assert result.freq == expected.freq
|
||||
|
||||
# non-monotonic
|
||||
base = DatetimeIndex(
|
||||
["2011-01-05", "2011-01-04", "2011-01-02", "2011-01-03"], tz=tz, name="idx"
|
||||
)
|
||||
|
||||
rng2 = DatetimeIndex(
|
||||
["2011-01-04", "2011-01-02", "2011-02-02", "2011-02-03"], tz=tz, name="idx"
|
||||
)
|
||||
expected2 = DatetimeIndex(["2011-01-04", "2011-01-02"], tz=tz, name="idx")
|
||||
|
||||
rng3 = DatetimeIndex(
|
||||
["2011-01-04", "2011-01-02", "2011-02-02", "2011-02-03"],
|
||||
tz=tz,
|
||||
name="other",
|
||||
)
|
||||
expected3 = DatetimeIndex(["2011-01-04", "2011-01-02"], tz=tz, name=None)
|
||||
|
||||
# GH 7880
|
||||
rng4 = date_range("7/1/2000", "7/31/2000", freq="D", tz=tz, name="idx")
|
||||
expected4 = DatetimeIndex([], tz=tz, name="idx")
|
||||
assert expected4.freq is None
|
||||
|
||||
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.freq == expected.freq
|
||||
|
||||
# parametrize over both anchored and non-anchored freqs, as they
|
||||
# have different code paths
|
||||
@pytest.mark.parametrize("freq", ["T", "B"])
|
||||
def test_intersection_empty(self, tz_aware_fixture, freq):
|
||||
# empty same freq GH2129
|
||||
tz = tz_aware_fixture
|
||||
rng = date_range("6/1/2000", "6/15/2000", freq=freq, tz=tz)
|
||||
result = rng[0:0].intersection(rng)
|
||||
assert len(result) == 0
|
||||
assert result.freq == rng.freq
|
||||
|
||||
result = rng.intersection(rng[0:0])
|
||||
assert len(result) == 0
|
||||
assert result.freq == rng.freq
|
||||
|
||||
# no overlap GH#33604
|
||||
check_freq = freq != "T" # We don't preserve freq on non-anchored offsets
|
||||
result = rng[:3].intersection(rng[-3:])
|
||||
tm.assert_index_equal(result, rng[:0])
|
||||
if check_freq:
|
||||
# We don't preserve freq on non-anchored offsets
|
||||
assert result.freq == rng.freq
|
||||
|
||||
# swapped left and right
|
||||
result = rng[-3:].intersection(rng[:3])
|
||||
tm.assert_index_equal(result, rng[:0])
|
||||
if check_freq:
|
||||
# We don't preserve freq on non-anchored offsets
|
||||
assert result.freq == rng.freq
|
||||
|
||||
def test_intersection_bug_1708(self):
|
||||
from pandas import DateOffset
|
||||
|
||||
index_1 = date_range("1/1/2012", periods=4, freq="12H")
|
||||
index_2 = index_1 + DateOffset(hours=1)
|
||||
|
||||
with tm.assert_produces_warning(FutureWarning):
|
||||
result = index_1 & index_2
|
||||
assert len(result) == 0
|
||||
|
||||
@pytest.mark.parametrize("tz", tz)
|
||||
def test_difference(self, tz, sort):
|
||||
rng_dates = ["1/2/2000", "1/3/2000", "1/1/2000", "1/4/2000", "1/5/2000"]
|
||||
|
||||
rng1 = DatetimeIndex(rng_dates, tz=tz)
|
||||
other1 = date_range("1/6/2000", freq="D", periods=5, tz=tz)
|
||||
expected1 = DatetimeIndex(rng_dates, tz=tz)
|
||||
|
||||
rng2 = DatetimeIndex(rng_dates, tz=tz)
|
||||
other2 = date_range("1/4/2000", freq="D", periods=5, tz=tz)
|
||||
expected2 = DatetimeIndex(rng_dates[:3], tz=tz)
|
||||
|
||||
rng3 = DatetimeIndex(rng_dates, tz=tz)
|
||||
other3 = DatetimeIndex([], tz=tz)
|
||||
expected3 = DatetimeIndex(rng_dates, tz=tz)
|
||||
|
||||
for rng, other, expected in [
|
||||
(rng1, other1, expected1),
|
||||
(rng2, other2, expected2),
|
||||
(rng3, other3, expected3),
|
||||
]:
|
||||
result_diff = rng.difference(other, 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_diff, expected)
|
||||
|
||||
def test_difference_freq(self, sort):
|
||||
# GH14323: difference of DatetimeIndex should not preserve frequency
|
||||
|
||||
index = date_range("20160920", "20160925", freq="D")
|
||||
other = date_range("20160921", "20160924", freq="D")
|
||||
expected = DatetimeIndex(["20160920", "20160925"], freq=None)
|
||||
idx_diff = index.difference(other, sort)
|
||||
tm.assert_index_equal(idx_diff, expected)
|
||||
tm.assert_attr_equal("freq", idx_diff, expected)
|
||||
|
||||
other = date_range("20160922", "20160925", freq="D")
|
||||
idx_diff = index.difference(other, sort)
|
||||
expected = DatetimeIndex(["20160920", "20160921"], freq=None)
|
||||
tm.assert_index_equal(idx_diff, expected)
|
||||
tm.assert_attr_equal("freq", idx_diff, expected)
|
||||
|
||||
def test_datetimeindex_diff(self, sort):
|
||||
dti1 = date_range(freq="Q-JAN", start=datetime(1997, 12, 31), periods=100)
|
||||
dti2 = date_range(freq="Q-JAN", start=datetime(1997, 12, 31), periods=98)
|
||||
assert len(dti1.difference(dti2, sort)) == 2
|
||||
|
||||
@pytest.mark.parametrize("tz", [None, "Asia/Tokyo", "US/Eastern"])
|
||||
def test_setops_preserve_freq(self, tz):
|
||||
rng = date_range("1/1/2000", "1/1/2002", name="idx", tz=tz)
|
||||
|
||||
result = rng[:50].union(rng[50:100])
|
||||
assert result.name == rng.name
|
||||
assert result.freq == rng.freq
|
||||
assert result.tz == rng.tz
|
||||
|
||||
result = rng[:50].union(rng[30:100])
|
||||
assert result.name == rng.name
|
||||
assert result.freq == rng.freq
|
||||
assert result.tz == rng.tz
|
||||
|
||||
result = rng[:50].union(rng[60:100])
|
||||
assert result.name == rng.name
|
||||
assert result.freq is None
|
||||
assert result.tz == rng.tz
|
||||
|
||||
result = rng[:50].intersection(rng[25:75])
|
||||
assert result.name == rng.name
|
||||
assert result.freqstr == "D"
|
||||
assert result.tz == rng.tz
|
||||
|
||||
nofreq = DatetimeIndex(list(rng[25:75]), name="other")
|
||||
result = rng[:50].union(nofreq)
|
||||
assert result.name is None
|
||||
assert result.freq == rng.freq
|
||||
assert result.tz == rng.tz
|
||||
|
||||
result = rng[:50].intersection(nofreq)
|
||||
assert result.name is None
|
||||
assert result.freq == rng.freq
|
||||
assert result.tz == rng.tz
|
||||
|
||||
def test_intersection_non_tick_no_fastpath(self):
|
||||
# GH#42104
|
||||
dti = DatetimeIndex(
|
||||
[
|
||||
"2018-12-31",
|
||||
"2019-03-31",
|
||||
"2019-06-30",
|
||||
"2019-09-30",
|
||||
"2019-12-31",
|
||||
"2020-03-31",
|
||||
],
|
||||
freq="Q-DEC",
|
||||
)
|
||||
result = dti[::2].intersection(dti[1::2])
|
||||
expected = dti[:0]
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
|
||||
class TestBusinessDatetimeIndex:
|
||||
def setup_method(self, method):
|
||||
self.rng = bdate_range(START, END)
|
||||
|
||||
def test_union(self, sort):
|
||||
# overlapping
|
||||
left = self.rng[:10]
|
||||
right = self.rng[5:10]
|
||||
|
||||
the_union = left.union(right, sort=sort)
|
||||
assert isinstance(the_union, DatetimeIndex)
|
||||
|
||||
# non-overlapping, gap in middle
|
||||
left = self.rng[:5]
|
||||
right = self.rng[10:]
|
||||
|
||||
the_union = left.union(right, sort=sort)
|
||||
assert isinstance(the_union, Index)
|
||||
|
||||
# non-overlapping, no gap
|
||||
left = self.rng[:5]
|
||||
right = self.rng[5:10]
|
||||
|
||||
the_union = left.union(right, sort=sort)
|
||||
assert isinstance(the_union, DatetimeIndex)
|
||||
|
||||
# order does not matter
|
||||
if sort is None:
|
||||
tm.assert_index_equal(right.union(left, sort=sort), the_union)
|
||||
else:
|
||||
expected = DatetimeIndex(list(right) + list(left))
|
||||
tm.assert_index_equal(right.union(left, sort=sort), expected)
|
||||
|
||||
# overlapping, but different offset
|
||||
rng = date_range(START, END, freq=BMonthEnd())
|
||||
|
||||
the_union = self.rng.union(rng, sort=sort)
|
||||
assert isinstance(the_union, DatetimeIndex)
|
||||
|
||||
def test_union_not_cacheable(self, sort):
|
||||
rng = date_range("1/1/2000", periods=50, freq=Minute())
|
||||
rng1 = rng[10:]
|
||||
rng2 = rng[:25]
|
||||
the_union = rng1.union(rng2, sort=sort)
|
||||
if sort is None:
|
||||
tm.assert_index_equal(the_union, rng)
|
||||
else:
|
||||
expected = DatetimeIndex(list(rng[10:]) + list(rng[:10]))
|
||||
tm.assert_index_equal(the_union, expected)
|
||||
|
||||
rng1 = rng[10:]
|
||||
rng2 = rng[15:35]
|
||||
the_union = rng1.union(rng2, sort=sort)
|
||||
expected = rng[10:]
|
||||
tm.assert_index_equal(the_union, expected)
|
||||
|
||||
def test_intersection(self):
|
||||
rng = date_range("1/1/2000", periods=50, freq=Minute())
|
||||
rng1 = rng[10:]
|
||||
rng2 = rng[:25]
|
||||
the_int = rng1.intersection(rng2)
|
||||
expected = rng[10:25]
|
||||
tm.assert_index_equal(the_int, expected)
|
||||
assert isinstance(the_int, DatetimeIndex)
|
||||
assert the_int.freq == rng.freq
|
||||
|
||||
the_int = rng1.intersection(rng2.view(DatetimeIndex))
|
||||
tm.assert_index_equal(the_int, expected)
|
||||
|
||||
# non-overlapping
|
||||
the_int = rng[:10].intersection(rng[10:])
|
||||
expected = DatetimeIndex([])
|
||||
tm.assert_index_equal(the_int, expected)
|
||||
|
||||
def test_intersection_bug(self):
|
||||
# GH #771
|
||||
a = bdate_range("11/30/2011", "12/31/2011")
|
||||
b = bdate_range("12/10/2011", "12/20/2011")
|
||||
result = a.intersection(b)
|
||||
tm.assert_index_equal(result, b)
|
||||
assert result.freq == b.freq
|
||||
|
||||
def test_intersection_list(self):
|
||||
# GH#35876
|
||||
# values is not an Index -> no name -> retain "a"
|
||||
values = [pd.Timestamp("2020-01-01"), pd.Timestamp("2020-02-01")]
|
||||
idx = DatetimeIndex(values, name="a")
|
||||
res = idx.intersection(values)
|
||||
tm.assert_index_equal(res, idx)
|
||||
|
||||
def test_month_range_union_tz_pytz(self, sort):
|
||||
from pytz import timezone
|
||||
|
||||
tz = timezone("US/Eastern")
|
||||
|
||||
early_start = datetime(2011, 1, 1)
|
||||
early_end = datetime(2011, 3, 1)
|
||||
|
||||
late_start = datetime(2011, 3, 1)
|
||||
late_end = datetime(2011, 5, 1)
|
||||
|
||||
early_dr = date_range(start=early_start, end=early_end, tz=tz, freq=MonthEnd())
|
||||
late_dr = date_range(start=late_start, end=late_end, tz=tz, freq=MonthEnd())
|
||||
|
||||
early_dr.union(late_dr, sort=sort)
|
||||
|
||||
@td.skip_if_windows
|
||||
def test_month_range_union_tz_dateutil(self, sort):
|
||||
from pandas._libs.tslibs.timezones import dateutil_gettz
|
||||
|
||||
tz = dateutil_gettz("US/Eastern")
|
||||
|
||||
early_start = datetime(2011, 1, 1)
|
||||
early_end = datetime(2011, 3, 1)
|
||||
|
||||
late_start = datetime(2011, 3, 1)
|
||||
late_end = datetime(2011, 5, 1)
|
||||
|
||||
early_dr = date_range(start=early_start, end=early_end, tz=tz, freq=MonthEnd())
|
||||
late_dr = date_range(start=late_start, end=late_end, tz=tz, freq=MonthEnd())
|
||||
|
||||
early_dr.union(late_dr, sort=sort)
|
||||
|
||||
@pytest.mark.parametrize("sort", [False, None])
|
||||
def test_intersection_duplicates(self, sort):
|
||||
# GH#38196
|
||||
idx1 = Index(
|
||||
[
|
||||
pd.Timestamp("2019-12-13"),
|
||||
pd.Timestamp("2019-12-12"),
|
||||
pd.Timestamp("2019-12-12"),
|
||||
]
|
||||
)
|
||||
result = idx1.intersection(idx1, sort=sort)
|
||||
expected = Index([pd.Timestamp("2019-12-13"), pd.Timestamp("2019-12-12")])
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
|
||||
class TestCustomDatetimeIndex:
|
||||
def setup_method(self, method):
|
||||
self.rng = bdate_range(START, END, freq="C")
|
||||
|
||||
def test_union(self, sort):
|
||||
# overlapping
|
||||
left = self.rng[:10]
|
||||
right = self.rng[5:10]
|
||||
|
||||
the_union = left.union(right, sort=sort)
|
||||
assert isinstance(the_union, DatetimeIndex)
|
||||
|
||||
# non-overlapping, gap in middle
|
||||
left = self.rng[:5]
|
||||
right = self.rng[10:]
|
||||
|
||||
the_union = left.union(right, sort)
|
||||
assert isinstance(the_union, Index)
|
||||
|
||||
# non-overlapping, no gap
|
||||
left = self.rng[:5]
|
||||
right = self.rng[5:10]
|
||||
|
||||
the_union = left.union(right, sort=sort)
|
||||
assert isinstance(the_union, DatetimeIndex)
|
||||
|
||||
# order does not matter
|
||||
if sort is None:
|
||||
tm.assert_index_equal(right.union(left, sort=sort), the_union)
|
||||
|
||||
# overlapping, but different offset
|
||||
rng = date_range(START, END, freq=BMonthEnd())
|
||||
|
||||
the_union = self.rng.union(rng, sort=sort)
|
||||
assert isinstance(the_union, DatetimeIndex)
|
||||
|
||||
def test_intersection_bug(self):
|
||||
# GH #771
|
||||
a = bdate_range("11/30/2011", "12/31/2011", freq="C")
|
||||
b = bdate_range("12/10/2011", "12/20/2011", freq="C")
|
||||
result = a.intersection(b)
|
||||
tm.assert_index_equal(result, b)
|
||||
assert result.freq == b.freq
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,77 @@
|
||||
from datetime import (
|
||||
datetime,
|
||||
timedelta,
|
||||
)
|
||||
|
||||
from pandas import (
|
||||
DatetimeIndex,
|
||||
NaT,
|
||||
Timestamp,
|
||||
)
|
||||
import pandas._testing as tm
|
||||
|
||||
|
||||
def test_unique(tz_naive_fixture):
|
||||
|
||||
idx = DatetimeIndex(["2017"] * 2, tz=tz_naive_fixture)
|
||||
expected = idx[:1]
|
||||
|
||||
result = idx.unique()
|
||||
tm.assert_index_equal(result, expected)
|
||||
# GH#21737
|
||||
# Ensure the underlying data is consistent
|
||||
assert result[0] == expected[0]
|
||||
|
||||
|
||||
def test_index_unique(rand_series_with_duplicate_datetimeindex):
|
||||
dups = rand_series_with_duplicate_datetimeindex
|
||||
index = dups.index
|
||||
|
||||
uniques = index.unique()
|
||||
expected = DatetimeIndex(
|
||||
[
|
||||
datetime(2000, 1, 2),
|
||||
datetime(2000, 1, 3),
|
||||
datetime(2000, 1, 4),
|
||||
datetime(2000, 1, 5),
|
||||
]
|
||||
)
|
||||
assert uniques.dtype == "M8[ns]" # sanity
|
||||
tm.assert_index_equal(uniques, expected)
|
||||
assert index.nunique() == 4
|
||||
|
||||
# GH#2563
|
||||
assert isinstance(uniques, DatetimeIndex)
|
||||
|
||||
dups_local = index.tz_localize("US/Eastern")
|
||||
dups_local.name = "foo"
|
||||
result = dups_local.unique()
|
||||
expected = DatetimeIndex(expected, name="foo")
|
||||
expected = expected.tz_localize("US/Eastern")
|
||||
assert result.tz is not None
|
||||
assert result.name == "foo"
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
|
||||
def test_index_unique2():
|
||||
# NaT, note this is excluded
|
||||
arr = [1370745748 + t for t in range(20)] + [NaT.value]
|
||||
idx = DatetimeIndex(arr * 3)
|
||||
tm.assert_index_equal(idx.unique(), DatetimeIndex(arr))
|
||||
assert idx.nunique() == 20
|
||||
assert idx.nunique(dropna=False) == 21
|
||||
|
||||
|
||||
def test_index_unique3():
|
||||
arr = [
|
||||
Timestamp("2013-06-09 02:42:28") + timedelta(seconds=t) for t in range(20)
|
||||
] + [NaT]
|
||||
idx = DatetimeIndex(arr * 3)
|
||||
tm.assert_index_equal(idx.unique(), DatetimeIndex(arr))
|
||||
assert idx.nunique() == 20
|
||||
assert idx.nunique(dropna=False) == 21
|
||||
|
||||
|
||||
def test_is_unique_monotonic(rand_series_with_duplicate_datetimeindex):
|
||||
index = rand_series_with_duplicate_datetimeindex.index
|
||||
assert not index.is_unique
|
Reference in New Issue
Block a user