Initial Debugging Completed and Execution Successful
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,30 @@
|
||||
from datetime import timedelta
|
||||
|
||||
from pandas import (
|
||||
Index,
|
||||
Timestamp,
|
||||
date_range,
|
||||
isna,
|
||||
)
|
||||
|
||||
|
||||
class TestAsOf:
|
||||
def test_asof_partial(self):
|
||||
index = date_range("2010-01-01", periods=2, freq="ME")
|
||||
expected = Timestamp("2010-02-28")
|
||||
result = index.asof("2010-02")
|
||||
assert result == expected
|
||||
assert not isinstance(result, Index)
|
||||
|
||||
def test_asof(self):
|
||||
index = date_range("2020-01-01", periods=10)
|
||||
|
||||
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)
|
||||
@@ -0,0 +1,338 @@
|
||||
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
|
||||
|
||||
|
||||
class TestDatetimeIndex:
|
||||
@pytest.mark.parametrize("tzstr", ["US/Eastern", "dateutil/US/Eastern"])
|
||||
def test_dti_astype_asobject_around_dst_transition(self, tzstr):
|
||||
# GH#1345
|
||||
|
||||
# dates around a dst transition
|
||||
rng = date_range("2/13/2010", "5/6/2010", tz=tzstr)
|
||||
|
||||
objs = rng.astype(object)
|
||||
for i, x in enumerate(objs):
|
||||
exval = rng[i]
|
||||
assert x == exval
|
||||
assert x.tzinfo == exval.tzinfo
|
||||
|
||||
objs = rng.astype(object)
|
||||
for i, x in enumerate(objs):
|
||||
exval = rng[i]
|
||||
assert x == exval
|
||||
assert x.tzinfo == exval.tzinfo
|
||||
|
||||
def test_astype(self):
|
||||
# GH 13149, GH 13209
|
||||
idx = DatetimeIndex(
|
||||
["2016-05-16", "NaT", NaT, np.nan], dtype="M8[ns]", 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(np.int64)
|
||||
expected = Index(
|
||||
[1463356800000000000] + [-9223372036854775808] * 3,
|
||||
dtype=np.int64,
|
||||
name="idx",
|
||||
)
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
def test_astype2(self):
|
||||
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")
|
||||
|
||||
with pytest.raises(TypeError, match=r"Do obj.astype\('int64'\)"):
|
||||
arr.astype("uint64")
|
||||
with pytest.raises(TypeError, match=r"Do obj.astype\('int64'\)"):
|
||||
arr.astype("uint32")
|
||||
|
||||
def test_astype_with_tz(self):
|
||||
# with tz
|
||||
rng = date_range("1/1/2000", periods=10, tz="US/Eastern")
|
||||
msg = "Cannot use .astype to convert from timezone-aware"
|
||||
with pytest.raises(TypeError, match=msg):
|
||||
# deprecated
|
||||
rng.astype("datetime64[ns]")
|
||||
with pytest.raises(TypeError, match=msg):
|
||||
# check DatetimeArray while we're here deprecated
|
||||
rng._data.astype("datetime64[ns]")
|
||||
|
||||
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
|
||||
msg = "Cannot use .astype to convert from timezone-naive"
|
||||
with pytest.raises(TypeError, match=msg):
|
||||
# dt64->dt64tz deprecated
|
||||
idx.astype("datetime64[ns, US/Eastern]")
|
||||
with pytest.raises(TypeError, match=msg):
|
||||
# dt64->dt64tz deprecated
|
||||
idx._data.astype("datetime64[ns, US/Eastern]")
|
||||
|
||||
def test_astype_str_nat(self, using_infer_string):
|
||||
# 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)
|
||||
if using_infer_string:
|
||||
expected = Index(["2016-05-16", None, None, None], dtype="str")
|
||||
else:
|
||||
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="str",
|
||||
)
|
||||
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="str",
|
||||
)
|
||||
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="str",
|
||||
)
|
||||
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="str",
|
||||
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], dtype="M8[ns]", 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")
|
||||
msg = "Cannot use .astype to convert from timezone-aware"
|
||||
with pytest.raises(TypeError, match=msg):
|
||||
# dt64tz->dt64 deprecated
|
||||
result = idx_tz.astype("datetime64[ns]")
|
||||
|
||||
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="ME", 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"
|
||||
if dtype == "datetime64":
|
||||
msg = "Casting to unit-less dtype 'datetime64' is not supported"
|
||||
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).as_unit("ns")._value]
|
||||
result = Index(val, name="idx").astype(dtype)
|
||||
expected = DatetimeIndex(["2018-01-01"], tz=tz, name="idx").as_unit("ns")
|
||||
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")
|
||||
dti = DatetimeIndex(["2000-01-01", "2000-01-02"], tz=tz).as_unit("ns")
|
||||
expected = pd.CategoricalIndex(
|
||||
dti,
|
||||
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,141 @@
|
||||
import pytest
|
||||
|
||||
from pandas import (
|
||||
DatetimeIndex,
|
||||
Series,
|
||||
date_range,
|
||||
)
|
||||
import pandas._testing as tm
|
||||
|
||||
|
||||
class TestDelete:
|
||||
def test_delete(self, unit):
|
||||
idx = date_range(
|
||||
start="2000-01-01", periods=5, freq="ME", name="idx", unit=unit
|
||||
)
|
||||
|
||||
# preserve freq
|
||||
expected_0 = date_range(
|
||||
start="2000-02-01", periods=4, freq="ME", name="idx", unit=unit
|
||||
)
|
||||
expected_4 = date_range(
|
||||
start="2000-01-01", periods=4, freq="ME", name="idx", unit=unit
|
||||
)
|
||||
|
||||
# reset freq to None
|
||||
expected_1 = DatetimeIndex(
|
||||
["2000-01-31", "2000-03-31", "2000-04-30", "2000-05-31"],
|
||||
freq=None,
|
||||
name="idx",
|
||||
).as_unit(unit)
|
||||
|
||||
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)
|
||||
|
||||
@pytest.mark.parametrize("tz", [None, "Asia/Tokyo", "US/Pacific"])
|
||||
def test_delete2(self, tz):
|
||||
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, unit):
|
||||
idx = date_range(
|
||||
start="2000-01-01", periods=10, freq="D", name="idx", unit=unit
|
||||
)
|
||||
|
||||
# preserve freq
|
||||
expected_0_2 = date_range(
|
||||
start="2000-01-04", periods=7, freq="D", name="idx", unit=unit
|
||||
)
|
||||
expected_7_9 = date_range(
|
||||
start="2000-01-01", periods=7, freq="D", name="idx", unit=unit
|
||||
)
|
||||
|
||||
# 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",
|
||||
).as_unit(unit)
|
||||
|
||||
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
|
||||
|
||||
# TODO: belongs in Series.drop tests?
|
||||
@pytest.mark.parametrize("tz", [None, "Asia/Tokyo", "US/Pacific"])
|
||||
def test_delete_slice2(self, tz, unit):
|
||||
dti = date_range(
|
||||
"2000-01-01 09:00", periods=10, freq="h", name="idx", tz=tz, unit=unit
|
||||
)
|
||||
ts = Series(
|
||||
1,
|
||||
index=dti,
|
||||
)
|
||||
# preserve freq
|
||||
result = ts.drop(ts.index[:5]).index
|
||||
expected = dti[5:]
|
||||
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 = dti[::2]._with_freq(None)
|
||||
tm.assert_index_equal(result, expected)
|
||||
assert result.name == expected.name
|
||||
assert result.freq == expected.freq
|
||||
assert result.tz == expected.tz
|
||||
@@ -0,0 +1,125 @@
|
||||
import numpy as np
|
||||
import pytest
|
||||
|
||||
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="ME", 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
|
||||
|
||||
@pytest.mark.parametrize("sort", [True, False])
|
||||
def test_factorize_no_freq_non_nano(self, tz_naive_fixture, sort):
|
||||
# GH#51978 case that does not go through the fastpath based on
|
||||
# non-None freq
|
||||
tz = tz_naive_fixture
|
||||
idx = date_range("2016-11-06", freq="h", periods=5, tz=tz)[[0, 4, 1, 3, 2]]
|
||||
exp_codes, exp_uniques = idx.factorize(sort=sort)
|
||||
|
||||
res_codes, res_uniques = idx.as_unit("s").factorize(sort=sort)
|
||||
|
||||
tm.assert_numpy_array_equal(res_codes, exp_codes)
|
||||
tm.assert_index_equal(res_uniques, exp_uniques.as_unit("s"))
|
||||
|
||||
res_codes, res_uniques = idx.as_unit("s").to_series().factorize(sort=sort)
|
||||
tm.assert_numpy_array_equal(res_codes, exp_codes)
|
||||
tm.assert_index_equal(res_uniques, exp_uniques.as_unit("s"))
|
||||
@@ -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,265 @@
|
||||
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, unit):
|
||||
idx = DatetimeIndex(
|
||||
["2000-01-04", "2000-01-01", "2000-01-02"], name="idx"
|
||||
).as_unit(unit)
|
||||
|
||||
result = idx.insert(2, datetime(2000, 1, 5))
|
||||
exp = DatetimeIndex(
|
||||
["2000-01-04", "2000-01-01", "2000-01-05", "2000-01-02"], name="idx"
|
||||
).as_unit(unit)
|
||||
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
|
||||
|
||||
def test_insert2(self, unit):
|
||||
idx = date_range("1/1/2000", periods=3, freq="ME", name="idx", unit=unit)
|
||||
|
||||
# preserve freq
|
||||
expected_0 = DatetimeIndex(
|
||||
["1999-12-31", "2000-01-31", "2000-02-29", "2000-03-31"],
|
||||
name="idx",
|
||||
freq="ME",
|
||||
).as_unit(unit)
|
||||
expected_3 = DatetimeIndex(
|
||||
["2000-01-31", "2000-02-29", "2000-03-31", "2000-04-30"],
|
||||
name="idx",
|
||||
freq="ME",
|
||||
).as_unit(unit)
|
||||
|
||||
# reset freq to None
|
||||
expected_1_nofreq = DatetimeIndex(
|
||||
["2000-01-31", "2000-01-31", "2000-02-29", "2000-03-31"],
|
||||
name="idx",
|
||||
freq=None,
|
||||
).as_unit(unit)
|
||||
expected_3_nofreq = DatetimeIndex(
|
||||
["2000-01-31", "2000-02-29", "2000-03-31", "2000-01-02"],
|
||||
name="idx",
|
||||
freq=None,
|
||||
).as_unit(unit)
|
||||
|
||||
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
|
||||
|
||||
def test_insert3(self, unit):
|
||||
idx = date_range("1/1/2000", periods=3, freq="ME", name="idx", unit=unit)
|
||||
|
||||
# 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,
|
||||
).as_unit(unit)
|
||||
tm.assert_index_equal(result, expected)
|
||||
assert result.name == expected.name
|
||||
assert result.freq is None
|
||||
|
||||
def test_insert4(self, unit):
|
||||
for tz in ["US/Pacific", "Asia/Singapore"]:
|
||||
idx = date_range(
|
||||
"1/1/2000 09:00", periods=6, freq="h", tz=tz, name="idx", unit=unit
|
||||
)
|
||||
# preserve freq
|
||||
expected = date_range(
|
||||
"1/1/2000 09:00", periods=7, freq="h", tz=tz, name="idx", unit=unit
|
||||
)
|
||||
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,
|
||||
).as_unit(unit)
|
||||
# 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
|
||||
# pre-2.0 with mismatched tzs we would cast to object
|
||||
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")
|
||||
result = idx.insert(3, item)
|
||||
expected = Index(
|
||||
list(idx[:3]) + [item.tz_convert(idx.tz)] + list(idx[3:]),
|
||||
name="idx",
|
||||
)
|
||||
assert expected.dtype == idx.dtype
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
item = datetime(2000, 1, 4, tzinfo=pytz.timezone("US/Eastern"))
|
||||
result = idx.insert(3, item)
|
||||
expected = Index(
|
||||
list(idx[:3]) + [item.astimezone(idx.tzinfo)] + list(idx[3:]),
|
||||
name="idx",
|
||||
)
|
||||
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,28 @@
|
||||
from pandas import (
|
||||
DataFrame,
|
||||
DatetimeIndex,
|
||||
date_range,
|
||||
)
|
||||
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)
|
||||
|
||||
|
||||
def test_dti_timestamp_isocalendar_fields():
|
||||
idx = date_range("2020-01-01", periods=10)
|
||||
expected = tuple(idx.isocalendar().iloc[-1].to_list())
|
||||
result = idx[-1].isocalendar()
|
||||
assert 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])
|
||||
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="ME", 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,95 @@
|
||||
from dateutil.tz import tzlocal
|
||||
import numpy as np
|
||||
import pytest
|
||||
|
||||
import pandas.util._test_decorators as td
|
||||
|
||||
from pandas import (
|
||||
DatetimeIndex,
|
||||
NaT,
|
||||
Timestamp,
|
||||
date_range,
|
||||
)
|
||||
import pandas._testing as tm
|
||||
|
||||
|
||||
class TestNormalize:
|
||||
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([NaT, Timestamp("2018-01-01 01:00:00")])
|
||||
result = dti.normalize()
|
||||
expected = DatetimeIndex([NaT, Timestamp("2018-01-01")])
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
def test_normalize_tz(self):
|
||||
rng = date_range("1/1/2000 9:30", periods=10, freq="D", tz="US/Eastern")
|
||||
|
||||
result = rng.normalize() # does not preserve freq
|
||||
expected = date_range("1/1/2000", periods=10, freq="D", tz="US/Eastern")
|
||||
tm.assert_index_equal(result, expected._with_freq(None))
|
||||
|
||||
assert result.is_normalized
|
||||
assert not rng.is_normalized
|
||||
|
||||
rng = date_range("1/1/2000 9:30", periods=10, freq="D", tz="UTC")
|
||||
|
||||
result = rng.normalize()
|
||||
expected = date_range("1/1/2000", periods=10, freq="D", tz="UTC")
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
assert result.is_normalized
|
||||
assert not rng.is_normalized
|
||||
|
||||
rng = date_range("1/1/2000 9:30", periods=10, freq="D", tz=tzlocal())
|
||||
result = rng.normalize() # does not preserve freq
|
||||
expected = date_range("1/1/2000", periods=10, freq="D", tz=tzlocal())
|
||||
tm.assert_index_equal(result, expected._with_freq(None))
|
||||
|
||||
assert result.is_normalized
|
||||
assert not rng.is_normalized
|
||||
|
||||
@td.skip_if_windows
|
||||
@pytest.mark.parametrize(
|
||||
"timezone",
|
||||
[
|
||||
"US/Pacific",
|
||||
"US/Eastern",
|
||||
"UTC",
|
||||
"Asia/Kolkata",
|
||||
"Asia/Shanghai",
|
||||
"Australia/Canberra",
|
||||
],
|
||||
)
|
||||
def test_normalize_tz_local(self, timezone):
|
||||
# GH#13459
|
||||
with tm.set_timezone(timezone):
|
||||
rng = date_range("1/1/2000 9:30", periods=10, freq="D", tz=tzlocal())
|
||||
|
||||
result = rng.normalize()
|
||||
expected = date_range("1/1/2000", periods=10, freq="D", tz=tzlocal())
|
||||
expected = expected._with_freq(None)
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
assert result.is_normalized
|
||||
assert not rng.is_normalized
|
||||
@@ -0,0 +1,83 @@
|
||||
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):
|
||||
rng = date_range("1/1/2000", "1/1/2001")
|
||||
|
||||
result = rng.repeat(5)
|
||||
assert result.freq is None
|
||||
assert len(result) == 5 * len(rng)
|
||||
|
||||
def test_repeat_range2(self, tz_naive_fixture, unit):
|
||||
tz = tz_naive_fixture
|
||||
index = date_range("2001-01-01", periods=2, freq="D", tz=tz, unit=unit)
|
||||
exp = DatetimeIndex(
|
||||
["2001-01-01", "2001-01-01", "2001-01-02", "2001-01-02"], tz=tz
|
||||
).as_unit(unit)
|
||||
for res in [index.repeat(2), np.repeat(index, 2)]:
|
||||
tm.assert_index_equal(res, exp)
|
||||
assert res.freq is None
|
||||
|
||||
def test_repeat_range3(self, tz_naive_fixture, unit):
|
||||
tz = tz_naive_fixture
|
||||
index = date_range("2001-01-01", periods=2, freq="2D", tz=tz, unit=unit)
|
||||
exp = DatetimeIndex(
|
||||
["2001-01-01", "2001-01-01", "2001-01-03", "2001-01-03"], tz=tz
|
||||
).as_unit(unit)
|
||||
for res in [index.repeat(2), np.repeat(index, 2)]:
|
||||
tm.assert_index_equal(res, exp)
|
||||
assert res.freq is None
|
||||
|
||||
def test_repeat_range4(self, tz_naive_fixture, unit):
|
||||
tz = tz_naive_fixture
|
||||
index = DatetimeIndex(["2001-01-01", "NaT", "2003-01-01"], tz=tz).as_unit(unit)
|
||||
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,
|
||||
).as_unit(unit)
|
||||
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, unit):
|
||||
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, unit=unit)
|
||||
|
||||
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),
|
||||
]
|
||||
).as_unit(unit)
|
||||
|
||||
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,31 @@
|
||||
from dateutil.tz import tzlocal
|
||||
import pytest
|
||||
|
||||
from pandas.compat import IS64
|
||||
|
||||
from pandas import date_range
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"freq,expected",
|
||||
[
|
||||
("YE", "day"),
|
||||
("QE", "day"),
|
||||
("ME", "day"),
|
||||
("D", "day"),
|
||||
("h", "hour"),
|
||||
("min", "minute"),
|
||||
("s", "second"),
|
||||
("ms", "millisecond"),
|
||||
("us", "microsecond"),
|
||||
],
|
||||
)
|
||||
def test_dti_resolution(request, tz_naive_fixture, freq, expected):
|
||||
tz = tz_naive_fixture
|
||||
if freq == "YE" and not IS64 and isinstance(tz, tzlocal):
|
||||
request.applymarker(
|
||||
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
|
||||
@@ -0,0 +1,221 @@
|
||||
import pytest
|
||||
|
||||
from pandas._libs.tslibs import to_offset
|
||||
from pandas._libs.tslibs.offsets import INVALID_FREQ_ERR_MSG
|
||||
|
||||
from pandas import (
|
||||
DatetimeIndex,
|
||||
Timestamp,
|
||||
date_range,
|
||||
)
|
||||
import pandas._testing as tm
|
||||
|
||||
|
||||
class TestDatetimeIndexRound:
|
||||
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",
|
||||
[
|
||||
("YE", "<YearEnd: month=12> is a non-fixed frequency"),
|
||||
("ME", "<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, unit):
|
||||
tz = tz_naive_fixture
|
||||
rng = date_range(start="2016-01-01", periods=5, freq="30Min", tz=tz, unit=unit)
|
||||
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),
|
||||
]
|
||||
).as_unit(unit)
|
||||
expected_elt = expected_rng[1]
|
||||
|
||||
result = rng.round(freq="h")
|
||||
tm.assert_index_equal(result, 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="ME")
|
||||
with pytest.raises(ValueError, match=msg):
|
||||
elt.round(freq="ME")
|
||||
|
||||
def test_round2(self, tz_naive_fixture):
|
||||
tz = tz_naive_fixture
|
||||
# GH#14440 & GH#15578
|
||||
index = DatetimeIndex(["2016-10-17 12:00:00.0015"], tz=tz).as_unit("ns")
|
||||
result = index.round("ms")
|
||||
expected = DatetimeIndex(["2016-10-17 12:00:00.002000"], tz=tz).as_unit("ns")
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
for freq in ["us", "ns"]:
|
||||
tm.assert_index_equal(index, index.round(freq))
|
||||
|
||||
def test_round3(self, tz_naive_fixture):
|
||||
tz = tz_naive_fixture
|
||||
index = DatetimeIndex(["2016-10-17 12:00:00.00149"], tz=tz).as_unit("ns")
|
||||
result = index.round("ms")
|
||||
expected = DatetimeIndex(["2016-10-17 12:00:00.001000"], tz=tz).as_unit("ns")
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
def test_round4(self, tz_naive_fixture):
|
||||
index = DatetimeIndex(["2016-10-17 12:00:00.001501031"], dtype="M8[ns]")
|
||||
result = index.round("10ns")
|
||||
expected = DatetimeIndex(["2016-10-17 12:00:00.001501030"], dtype="M8[ns]")
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
ts = "2016-10-17 12:00:00.001501031"
|
||||
dti = DatetimeIndex([ts], dtype="M8[ns]")
|
||||
with tm.assert_produces_warning(False):
|
||||
dti.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),
|
||||
]
|
||||
).as_unit("ns")
|
||||
|
||||
result = rng.round(freq="2min")
|
||||
tm.assert_index_equal(result, 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", "15min", ["2018-01-01 00:15:00"]),
|
||||
(["2018-01-01 00:15:00"], "floor", "15min", ["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"
|
||||
@@ -0,0 +1,169 @@
|
||||
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, unit):
|
||||
# GH#9903
|
||||
tz = tz_naive_fixture
|
||||
idx = DatetimeIndex([], name="xxx", tz=tz).as_unit(unit)
|
||||
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",
|
||||
).as_unit(unit)
|
||||
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",
|
||||
).as_unit(unit)
|
||||
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",
|
||||
).as_unit(unit)
|
||||
tm.assert_index_equal(idx.shift(-3, freq="h"), exp)
|
||||
|
||||
def test_dti_shift_freqs(self, unit):
|
||||
# test shift for DatetimeIndex and non DatetimeIndex
|
||||
# GH#8083
|
||||
drange = date_range("20130101", periods=5, unit=unit)
|
||||
result = drange.shift(1)
|
||||
expected = DatetimeIndex(
|
||||
["2013-01-02", "2013-01-03", "2013-01-04", "2013-01-05", "2013-01-06"],
|
||||
dtype=f"M8[{unit}]",
|
||||
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"],
|
||||
dtype=f"M8[{unit}]",
|
||||
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"],
|
||||
dtype=f"M8[{unit}]",
|
||||
freq="D",
|
||||
)
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
def test_dti_shift_int(self, unit):
|
||||
rng = date_range("1/1/2000", periods=20, unit=unit)
|
||||
|
||||
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, unit):
|
||||
# GH#19147
|
||||
dti = DatetimeIndex(["2011-01-01 10:00", "2011-01-01"], freq=None).as_unit(unit)
|
||||
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, unit):
|
||||
dr = date_range("2011/1/1", "2012/1/1", freq="W-FRI", unit=unit)
|
||||
dr_tz = dr.tz_localize(tzstr)
|
||||
|
||||
result = dr_tz.shift(1, "10min")
|
||||
assert result.tz == dr_tz.tz
|
||||
|
||||
def test_dti_shift_across_dst(self, unit):
|
||||
# GH 8616
|
||||
idx = date_range(
|
||||
"2013-11-03", tz="America/Chicago", periods=7, freq="h", unit=unit
|
||||
)
|
||||
ser = Series(index=idx[:-1], dtype=object)
|
||||
result = ser.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, unit):
|
||||
# GH 8616
|
||||
dt = datetime(2014, 11, 14, 0)
|
||||
dt_est = pytz.timezone("EST").localize(dt)
|
||||
idx = DatetimeIndex([dt_est]).as_unit(unit)
|
||||
ser = Series(data=[1], index=idx)
|
||||
result = ser.shift(shift, freq="h")
|
||||
exp_index = DatetimeIndex([result_time], tz="EST").as_unit(unit)
|
||||
expected = Series(1, index=exp_index)
|
||||
tm.assert_series_equal(result, expected)
|
||||
|
||||
def test_shift_periods(self, unit):
|
||||
# GH#22458 : argument 'n' was deprecated in favor of 'periods'
|
||||
idx = date_range(start=START, end=END, periods=3, unit=unit)
|
||||
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, unit):
|
||||
rng = date_range(START, END, freq=freq, unit=unit)
|
||||
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, unit):
|
||||
rng = date_range(START, END, freq=pd.offsets.BMonthEnd(), unit=unit)
|
||||
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(), unit=unit)
|
||||
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, unit):
|
||||
# GH#14811
|
||||
dti = date_range(start="2016-10-21", end="2016-10-21", freq="BME", unit=unit)
|
||||
result = dti.shift(1)
|
||||
tm.assert_index_equal(result, dti)
|
||||
@@ -0,0 +1,47 @@
|
||||
import pytest
|
||||
|
||||
from pandas import (
|
||||
DatetimeIndex,
|
||||
date_range,
|
||||
)
|
||||
import pandas._testing as tm
|
||||
|
||||
|
||||
@pytest.mark.parametrize("tz", [None, "Asia/Shanghai", "Europe/Berlin"])
|
||||
@pytest.mark.parametrize("name", [None, "my_dti"])
|
||||
@pytest.mark.parametrize("unit", ["ns", "us", "ms", "s"])
|
||||
def test_dti_snap(name, tz, unit):
|
||||
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",
|
||||
)
|
||||
dti = dti.as_unit(unit)
|
||||
|
||||
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])
|
||||
expected = expected.as_unit(unit)
|
||||
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])
|
||||
expected = expected.as_unit(unit)
|
||||
tm.assert_index_equal(result, expected)
|
||||
assert result.tz == expected.tz
|
||||
assert result.freq is None
|
||||
assert expected.freq is None
|
||||
@@ -0,0 +1,28 @@
|
||||
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")
|
||||
result = idx.to_frame(name=None)
|
||||
exp_idx = Index([None], dtype=object)
|
||||
tm.assert_index_equal(exp_idx, result.columns)
|
||||
|
||||
result = idx.rename("foo").to_frame(name=None)
|
||||
exp_idx = Index([None], dtype=object)
|
||||
tm.assert_index_equal(exp_idx, result.columns)
|
||||
@@ -0,0 +1,45 @@
|
||||
import numpy as np
|
||||
|
||||
from pandas import (
|
||||
Index,
|
||||
Timestamp,
|
||||
date_range,
|
||||
)
|
||||
import pandas._testing as tm
|
||||
|
||||
|
||||
class TestDateTimeIndexToJulianDate:
|
||||
def test_1700(self):
|
||||
dr = date_range(start=Timestamp("1710-10-01"), periods=5, freq="D")
|
||||
r1 = Index([x.to_julian_date() for x in dr])
|
||||
r2 = dr.to_julian_date()
|
||||
assert isinstance(r2, Index) and r2.dtype == np.float64
|
||||
tm.assert_index_equal(r1, r2)
|
||||
|
||||
def test_2000(self):
|
||||
dr = date_range(start=Timestamp("2000-02-27"), periods=5, freq="D")
|
||||
r1 = Index([x.to_julian_date() for x in dr])
|
||||
r2 = dr.to_julian_date()
|
||||
assert isinstance(r2, Index) and r2.dtype == np.float64
|
||||
tm.assert_index_equal(r1, r2)
|
||||
|
||||
def test_hour(self):
|
||||
dr = date_range(start=Timestamp("2000-02-27"), periods=5, freq="h")
|
||||
r1 = Index([x.to_julian_date() for x in dr])
|
||||
r2 = dr.to_julian_date()
|
||||
assert isinstance(r2, Index) and r2.dtype == np.float64
|
||||
tm.assert_index_equal(r1, r2)
|
||||
|
||||
def test_minute(self):
|
||||
dr = date_range(start=Timestamp("2000-02-27"), periods=5, freq="min")
|
||||
r1 = Index([x.to_julian_date() for x in dr])
|
||||
r2 = dr.to_julian_date()
|
||||
assert isinstance(r2, Index) and r2.dtype == np.float64
|
||||
tm.assert_index_equal(r1, r2)
|
||||
|
||||
def test_second(self):
|
||||
dr = date_range(start=Timestamp("2000-02-27"), periods=5, freq="s")
|
||||
r1 = Index([x.to_julian_date() for x in dr])
|
||||
r2 = dr.to_julian_date()
|
||||
assert isinstance(r2, Index) and r2.dtype == np.float64
|
||||
tm.assert_index_equal(r1, r2)
|
||||
@@ -0,0 +1,225 @@
|
||||
import dateutil.tz
|
||||
from dateutil.tz import tzlocal
|
||||
import pytest
|
||||
import pytz
|
||||
|
||||
from pandas._libs.tslibs.ccalendar import MONTHS
|
||||
from pandas._libs.tslibs.offsets import MonthEnd
|
||||
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="ME")
|
||||
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", ["BQE", "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 == "QE-DEC"
|
||||
|
||||
@pytest.mark.parametrize("off", ["BYE", "YS", "BYS"])
|
||||
def test_to_period_annualish(self, off):
|
||||
rng = date_range("01-Jan-2012", periods=8, freq=off)
|
||||
prng = rng.to_period()
|
||||
assert prng.freq == "YE-DEC"
|
||||
|
||||
def test_to_period_monthish(self):
|
||||
offsets = ["MS", "BME"]
|
||||
for off in offsets:
|
||||
rng = date_range("01-Jan-2012", periods=8, freq=off)
|
||||
prng = rng.to_period()
|
||||
assert prng.freqstr == "M"
|
||||
|
||||
rng = date_range("01-Jan-2012", periods=8, freq="ME")
|
||||
prng = rng.to_period()
|
||||
assert prng.freqstr == "M"
|
||||
|
||||
with pytest.raises(ValueError, match=INVALID_FREQ_ERR_MSG):
|
||||
date_range("01-Jan-2012", periods=8, freq="EOM")
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"freq_offset, freq_period",
|
||||
[
|
||||
("2ME", "2M"),
|
||||
(MonthEnd(2), MonthEnd(2)),
|
||||
],
|
||||
)
|
||||
def test_dti_to_period_2monthish(self, freq_offset, freq_period):
|
||||
dti = date_range("2020-01-01", periods=3, freq=freq_offset)
|
||||
pi = dti.to_period()
|
||||
|
||||
tm.assert_index_equal(pi, period_range("2020-01", "2020-05", freq=freq_period))
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"freq, freq_depr",
|
||||
[
|
||||
("2ME", "2M"),
|
||||
("2QE", "2Q"),
|
||||
("2QE-SEP", "2Q-SEP"),
|
||||
("1YE", "1Y"),
|
||||
("2YE-MAR", "2Y-MAR"),
|
||||
("1YE", "1A"),
|
||||
("2YE-MAR", "2A-MAR"),
|
||||
],
|
||||
)
|
||||
def test_to_period_frequency_M_Q_Y_A_deprecated(self, freq, freq_depr):
|
||||
# GH#9586
|
||||
msg = f"'{freq_depr[1:]}' is deprecated and will be removed "
|
||||
f"in a future version, please use '{freq[1:]}' instead."
|
||||
|
||||
rng = date_range("01-Jan-2012", periods=8, freq=freq)
|
||||
prng = rng.to_period()
|
||||
with tm.assert_produces_warning(FutureWarning, match=msg):
|
||||
assert prng.freq == freq_depr
|
||||
|
||||
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(UserWarning):
|
||||
pi1 = rng.to_period("5min")
|
||||
|
||||
with tm.assert_produces_warning(UserWarning):
|
||||
pi2 = rng.to_period()
|
||||
|
||||
tm.assert_index_equal(pi1, pi2)
|
||||
|
||||
@pytest.mark.filterwarnings(r"ignore:PeriodDtype\[B\] is deprecated:FutureWarning")
|
||||
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="ms")
|
||||
assert 2 == len(period)
|
||||
assert period[0] == Period("2007-01-01 10:11:12.123Z", "ms")
|
||||
assert period[1] == Period("2007-01-01 10:11:13.789Z", "ms")
|
||||
|
||||
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="us")
|
||||
assert 2 == len(period)
|
||||
assert period[0] == Period("2007-01-01 10:11:12.123456Z", "us")
|
||||
assert period[1] == Period("2007-01-01 10:11:13.789123Z", "us")
|
||||
|
||||
@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
|
||||
|
||||
result = ts.to_period()[0]
|
||||
expected = ts[0].to_period(ts.freq)
|
||||
|
||||
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(ts.freq)
|
||||
|
||||
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):
|
||||
result = ts.to_period()[0]
|
||||
expected = ts[0].to_period(ts.freq)
|
||||
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)
|
||||
|
||||
@pytest.mark.parametrize("freq", ["2BMS", "1SME-15"])
|
||||
def test_to_period_offsets_not_supported(self, freq):
|
||||
# GH#56243
|
||||
msg = f"{freq[1:]} is not supported as period frequency"
|
||||
ts = date_range("1/1/2012", periods=4, freq=freq)
|
||||
with pytest.raises(ValueError, match=msg):
|
||||
ts.to_period()
|
||||
@@ -0,0 +1,51 @@
|
||||
from datetime import (
|
||||
datetime,
|
||||
timezone,
|
||||
)
|
||||
|
||||
import dateutil.parser
|
||||
import dateutil.tz
|
||||
from dateutil.tz import tzlocal
|
||||
import numpy as np
|
||||
|
||||
from pandas import (
|
||||
DatetimeIndex,
|
||||
date_range,
|
||||
to_datetime,
|
||||
)
|
||||
import pandas._testing as tm
|
||||
from pandas.tests.indexes.datetimes.test_timezones import FixedOffset
|
||||
|
||||
fixed_off = FixedOffset(-420, "-07:00")
|
||||
|
||||
|
||||
class TestToPyDatetime:
|
||||
def test_dti_to_pydatetime(self):
|
||||
dt = dateutil.parser.parse("2012-06-13T01:39:00Z")
|
||||
dt = dt.replace(tzinfo=tzlocal())
|
||||
|
||||
arr = np.array([dt], dtype=object)
|
||||
|
||||
result = to_datetime(arr, utc=True)
|
||||
assert result.tz is timezone.utc
|
||||
|
||||
rng = date_range("2012-11-03 03:00", "2012-11-05 03:00", tz=tzlocal())
|
||||
arr = rng.to_pydatetime()
|
||||
result = to_datetime(arr, utc=True)
|
||||
assert result.tz is timezone.utc
|
||||
|
||||
def test_dti_to_pydatetime_fizedtz(self):
|
||||
dates = np.array(
|
||||
[
|
||||
datetime(2000, 1, 1, tzinfo=fixed_off),
|
||||
datetime(2000, 1, 2, tzinfo=fixed_off),
|
||||
datetime(2000, 1, 3, tzinfo=fixed_off),
|
||||
]
|
||||
)
|
||||
dti = DatetimeIndex(dates)
|
||||
|
||||
result = dti.to_pydatetime()
|
||||
tm.assert_numpy_array_equal(dates, result)
|
||||
|
||||
result = dti._mpl_repr()
|
||||
tm.assert_numpy_array_equal(dates, result)
|
||||
@@ -0,0 +1,18 @@
|
||||
import numpy as np
|
||||
|
||||
from pandas import (
|
||||
DatetimeIndex,
|
||||
Series,
|
||||
)
|
||||
import pandas._testing as tm
|
||||
|
||||
|
||||
class TestToSeries:
|
||||
def test_to_series(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")
|
||||
result = idx.to_series(index=[0, 1])
|
||||
assert expected.dtype == idx.dtype
|
||||
tm.assert_series_equal(result, expected)
|
||||
@@ -0,0 +1,283 @@
|
||||
from datetime import datetime
|
||||
|
||||
import dateutil.tz
|
||||
from dateutil.tz import gettz
|
||||
import numpy as np
|
||||
import pytest
|
||||
import pytz
|
||||
|
||||
from pandas._libs.tslibs import timezones
|
||||
|
||||
from pandas import (
|
||||
DatetimeIndex,
|
||||
Index,
|
||||
NaT,
|
||||
Timestamp,
|
||||
date_range,
|
||||
offsets,
|
||||
)
|
||||
import pandas._testing as tm
|
||||
|
||||
|
||||
class TestTZConvert:
|
||||
def test_tz_convert_nat(self):
|
||||
# GH#5546
|
||||
dates = [NaT]
|
||||
idx = DatetimeIndex(dates)
|
||||
idx = idx.tz_localize("US/Pacific")
|
||||
tm.assert_index_equal(idx, DatetimeIndex(dates, tz="US/Pacific"))
|
||||
idx = idx.tz_convert("US/Eastern")
|
||||
tm.assert_index_equal(idx, DatetimeIndex(dates, tz="US/Eastern"))
|
||||
idx = idx.tz_convert("UTC")
|
||||
tm.assert_index_equal(idx, DatetimeIndex(dates, tz="UTC"))
|
||||
|
||||
dates = ["2010-12-01 00:00", "2010-12-02 00:00", NaT]
|
||||
idx = DatetimeIndex(dates)
|
||||
idx = idx.tz_localize("US/Pacific")
|
||||
tm.assert_index_equal(idx, DatetimeIndex(dates, tz="US/Pacific"))
|
||||
idx = idx.tz_convert("US/Eastern")
|
||||
expected = ["2010-12-01 03:00", "2010-12-02 03:00", NaT]
|
||||
tm.assert_index_equal(idx, DatetimeIndex(expected, tz="US/Eastern"))
|
||||
|
||||
idx = idx + offsets.Hour(5)
|
||||
expected = ["2010-12-01 08:00", "2010-12-02 08:00", NaT]
|
||||
tm.assert_index_equal(idx, DatetimeIndex(expected, tz="US/Eastern"))
|
||||
idx = idx.tz_convert("US/Pacific")
|
||||
expected = ["2010-12-01 05:00", "2010-12-02 05:00", NaT]
|
||||
tm.assert_index_equal(idx, DatetimeIndex(expected, tz="US/Pacific"))
|
||||
|
||||
idx = idx + np.timedelta64(3, "h")
|
||||
expected = ["2010-12-01 08:00", "2010-12-02 08:00", NaT]
|
||||
tm.assert_index_equal(idx, DatetimeIndex(expected, tz="US/Pacific"))
|
||||
|
||||
idx = idx.tz_convert("US/Eastern")
|
||||
expected = ["2010-12-01 11:00", "2010-12-02 11:00", NaT]
|
||||
tm.assert_index_equal(idx, DatetimeIndex(expected, tz="US/Eastern"))
|
||||
|
||||
@pytest.mark.parametrize("prefix", ["", "dateutil/"])
|
||||
def test_dti_tz_convert_compat_timestamp(self, prefix):
|
||||
strdates = ["1/1/2012", "3/1/2012", "4/1/2012"]
|
||||
idx = DatetimeIndex(strdates, tz=prefix + "US/Eastern")
|
||||
|
||||
conv = idx[0].tz_convert(prefix + "US/Pacific")
|
||||
expected = idx.tz_convert(prefix + "US/Pacific")[0]
|
||||
|
||||
assert conv == expected
|
||||
|
||||
def test_dti_tz_convert_hour_overflow_dst(self):
|
||||
# Regression test for GH#13306
|
||||
|
||||
# sorted case US/Eastern -> UTC
|
||||
ts = ["2008-05-12 09:50:00", "2008-12-12 09:50:35", "2009-05-12 09:50:32"]
|
||||
tt = DatetimeIndex(ts).tz_localize("US/Eastern")
|
||||
ut = tt.tz_convert("UTC")
|
||||
expected = Index([13, 14, 13], dtype=np.int32)
|
||||
tm.assert_index_equal(ut.hour, expected)
|
||||
|
||||
# sorted case UTC -> US/Eastern
|
||||
ts = ["2008-05-12 13:50:00", "2008-12-12 14:50:35", "2009-05-12 13:50:32"]
|
||||
tt = DatetimeIndex(ts).tz_localize("UTC")
|
||||
ut = tt.tz_convert("US/Eastern")
|
||||
expected = Index([9, 9, 9], dtype=np.int32)
|
||||
tm.assert_index_equal(ut.hour, expected)
|
||||
|
||||
# unsorted case US/Eastern -> UTC
|
||||
ts = ["2008-05-12 09:50:00", "2008-12-12 09:50:35", "2008-05-12 09:50:32"]
|
||||
tt = DatetimeIndex(ts).tz_localize("US/Eastern")
|
||||
ut = tt.tz_convert("UTC")
|
||||
expected = Index([13, 14, 13], dtype=np.int32)
|
||||
tm.assert_index_equal(ut.hour, expected)
|
||||
|
||||
# unsorted case UTC -> US/Eastern
|
||||
ts = ["2008-05-12 13:50:00", "2008-12-12 14:50:35", "2008-05-12 13:50:32"]
|
||||
tt = DatetimeIndex(ts).tz_localize("UTC")
|
||||
ut = tt.tz_convert("US/Eastern")
|
||||
expected = Index([9, 9, 9], dtype=np.int32)
|
||||
tm.assert_index_equal(ut.hour, expected)
|
||||
|
||||
@pytest.mark.parametrize("tz", ["US/Eastern", "dateutil/US/Eastern"])
|
||||
def test_dti_tz_convert_hour_overflow_dst_timestamps(self, tz):
|
||||
# Regression test for GH#13306
|
||||
|
||||
# sorted case US/Eastern -> UTC
|
||||
ts = [
|
||||
Timestamp("2008-05-12 09:50:00", tz=tz),
|
||||
Timestamp("2008-12-12 09:50:35", tz=tz),
|
||||
Timestamp("2009-05-12 09:50:32", tz=tz),
|
||||
]
|
||||
tt = DatetimeIndex(ts)
|
||||
ut = tt.tz_convert("UTC")
|
||||
expected = Index([13, 14, 13], dtype=np.int32)
|
||||
tm.assert_index_equal(ut.hour, expected)
|
||||
|
||||
# sorted case UTC -> US/Eastern
|
||||
ts = [
|
||||
Timestamp("2008-05-12 13:50:00", tz="UTC"),
|
||||
Timestamp("2008-12-12 14:50:35", tz="UTC"),
|
||||
Timestamp("2009-05-12 13:50:32", tz="UTC"),
|
||||
]
|
||||
tt = DatetimeIndex(ts)
|
||||
ut = tt.tz_convert("US/Eastern")
|
||||
expected = Index([9, 9, 9], dtype=np.int32)
|
||||
tm.assert_index_equal(ut.hour, expected)
|
||||
|
||||
# unsorted case US/Eastern -> UTC
|
||||
ts = [
|
||||
Timestamp("2008-05-12 09:50:00", tz=tz),
|
||||
Timestamp("2008-12-12 09:50:35", tz=tz),
|
||||
Timestamp("2008-05-12 09:50:32", tz=tz),
|
||||
]
|
||||
tt = DatetimeIndex(ts)
|
||||
ut = tt.tz_convert("UTC")
|
||||
expected = Index([13, 14, 13], dtype=np.int32)
|
||||
tm.assert_index_equal(ut.hour, expected)
|
||||
|
||||
# unsorted case UTC -> US/Eastern
|
||||
ts = [
|
||||
Timestamp("2008-05-12 13:50:00", tz="UTC"),
|
||||
Timestamp("2008-12-12 14:50:35", tz="UTC"),
|
||||
Timestamp("2008-05-12 13:50:32", tz="UTC"),
|
||||
]
|
||||
tt = DatetimeIndex(ts)
|
||||
ut = tt.tz_convert("US/Eastern")
|
||||
expected = Index([9, 9, 9], dtype=np.int32)
|
||||
tm.assert_index_equal(ut.hour, expected)
|
||||
|
||||
@pytest.mark.parametrize("freq, n", [("h", 1), ("min", 60), ("s", 3600)])
|
||||
def test_dti_tz_convert_trans_pos_plus_1__bug(self, freq, n):
|
||||
# Regression test for tslib.tz_convert(vals, tz1, tz2).
|
||||
# See GH#4496 for details.
|
||||
idx = date_range(datetime(2011, 3, 26, 23), datetime(2011, 3, 27, 1), freq=freq)
|
||||
idx = idx.tz_localize("UTC")
|
||||
idx = idx.tz_convert("Europe/Moscow")
|
||||
|
||||
expected = np.repeat(np.array([3, 4, 5]), np.array([n, n, 1]))
|
||||
tm.assert_index_equal(idx.hour, Index(expected, dtype=np.int32))
|
||||
|
||||
def test_dti_tz_convert_dst(self):
|
||||
for freq, n in [("h", 1), ("min", 60), ("s", 3600)]:
|
||||
# Start DST
|
||||
idx = date_range(
|
||||
"2014-03-08 23:00", "2014-03-09 09:00", freq=freq, tz="UTC"
|
||||
)
|
||||
idx = idx.tz_convert("US/Eastern")
|
||||
expected = np.repeat(
|
||||
np.array([18, 19, 20, 21, 22, 23, 0, 1, 3, 4, 5]),
|
||||
np.array([n, n, n, n, n, n, n, n, n, n, 1]),
|
||||
)
|
||||
tm.assert_index_equal(idx.hour, Index(expected, dtype=np.int32))
|
||||
|
||||
idx = date_range(
|
||||
"2014-03-08 18:00", "2014-03-09 05:00", freq=freq, tz="US/Eastern"
|
||||
)
|
||||
idx = idx.tz_convert("UTC")
|
||||
expected = np.repeat(
|
||||
np.array([23, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]),
|
||||
np.array([n, n, n, n, n, n, n, n, n, n, 1]),
|
||||
)
|
||||
tm.assert_index_equal(idx.hour, Index(expected, dtype=np.int32))
|
||||
|
||||
# End DST
|
||||
idx = date_range(
|
||||
"2014-11-01 23:00", "2014-11-02 09:00", freq=freq, tz="UTC"
|
||||
)
|
||||
idx = idx.tz_convert("US/Eastern")
|
||||
expected = np.repeat(
|
||||
np.array([19, 20, 21, 22, 23, 0, 1, 1, 2, 3, 4]),
|
||||
np.array([n, n, n, n, n, n, n, n, n, n, 1]),
|
||||
)
|
||||
tm.assert_index_equal(idx.hour, Index(expected, dtype=np.int32))
|
||||
|
||||
idx = date_range(
|
||||
"2014-11-01 18:00", "2014-11-02 05:00", freq=freq, tz="US/Eastern"
|
||||
)
|
||||
idx = idx.tz_convert("UTC")
|
||||
expected = np.repeat(
|
||||
np.array([22, 23, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]),
|
||||
np.array([n, n, n, n, n, n, n, n, n, n, n, n, 1]),
|
||||
)
|
||||
tm.assert_index_equal(idx.hour, Index(expected, dtype=np.int32))
|
||||
|
||||
# daily
|
||||
# Start DST
|
||||
idx = date_range("2014-03-08 00:00", "2014-03-09 00:00", freq="D", tz="UTC")
|
||||
idx = idx.tz_convert("US/Eastern")
|
||||
tm.assert_index_equal(idx.hour, Index([19, 19], dtype=np.int32))
|
||||
|
||||
idx = date_range(
|
||||
"2014-03-08 00:00", "2014-03-09 00:00", freq="D", tz="US/Eastern"
|
||||
)
|
||||
idx = idx.tz_convert("UTC")
|
||||
tm.assert_index_equal(idx.hour, Index([5, 5], dtype=np.int32))
|
||||
|
||||
# End DST
|
||||
idx = date_range("2014-11-01 00:00", "2014-11-02 00:00", freq="D", tz="UTC")
|
||||
idx = idx.tz_convert("US/Eastern")
|
||||
tm.assert_index_equal(idx.hour, Index([20, 20], dtype=np.int32))
|
||||
|
||||
idx = date_range(
|
||||
"2014-11-01 00:00", "2014-11-02 000:00", freq="D", tz="US/Eastern"
|
||||
)
|
||||
idx = idx.tz_convert("UTC")
|
||||
tm.assert_index_equal(idx.hour, Index([4, 4], dtype=np.int32))
|
||||
|
||||
def test_tz_convert_roundtrip(self, tz_aware_fixture):
|
||||
tz = tz_aware_fixture
|
||||
idx1 = date_range(start="2014-01-01", end="2014-12-31", freq="ME", tz="UTC")
|
||||
exp1 = date_range(start="2014-01-01", end="2014-12-31", freq="ME")
|
||||
|
||||
idx2 = date_range(start="2014-01-01", end="2014-12-31", freq="D", tz="UTC")
|
||||
exp2 = date_range(start="2014-01-01", end="2014-12-31", freq="D")
|
||||
|
||||
idx3 = date_range(start="2014-01-01", end="2014-03-01", freq="h", tz="UTC")
|
||||
exp3 = date_range(start="2014-01-01", end="2014-03-01", freq="h")
|
||||
|
||||
idx4 = date_range(start="2014-08-01", end="2014-10-31", freq="min", tz="UTC")
|
||||
exp4 = date_range(start="2014-08-01", end="2014-10-31", freq="min")
|
||||
|
||||
for idx, expected in [(idx1, exp1), (idx2, exp2), (idx3, exp3), (idx4, exp4)]:
|
||||
converted = idx.tz_convert(tz)
|
||||
reset = converted.tz_convert(None)
|
||||
tm.assert_index_equal(reset, expected)
|
||||
assert reset.tzinfo is None
|
||||
expected = converted.tz_convert("UTC").tz_localize(None)
|
||||
expected = expected._with_freq("infer")
|
||||
tm.assert_index_equal(reset, expected)
|
||||
|
||||
def test_dti_tz_convert_tzlocal(self):
|
||||
# GH#13583
|
||||
# tz_convert doesn't affect to internal
|
||||
dti = date_range(start="2001-01-01", end="2001-03-01", tz="UTC")
|
||||
dti2 = dti.tz_convert(dateutil.tz.tzlocal())
|
||||
tm.assert_numpy_array_equal(dti2.asi8, dti.asi8)
|
||||
|
||||
dti = date_range(start="2001-01-01", end="2001-03-01", tz=dateutil.tz.tzlocal())
|
||||
dti2 = dti.tz_convert(None)
|
||||
tm.assert_numpy_array_equal(dti2.asi8, dti.asi8)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"tz",
|
||||
[
|
||||
"US/Eastern",
|
||||
"dateutil/US/Eastern",
|
||||
pytz.timezone("US/Eastern"),
|
||||
gettz("US/Eastern"),
|
||||
],
|
||||
)
|
||||
def test_dti_tz_convert_utc_to_local_no_modify(self, tz):
|
||||
rng = date_range("3/11/2012", "3/12/2012", freq="h", tz="utc")
|
||||
rng_eastern = rng.tz_convert(tz)
|
||||
|
||||
# Values are unmodified
|
||||
tm.assert_numpy_array_equal(rng.asi8, rng_eastern.asi8)
|
||||
|
||||
assert timezones.tz_compare(rng_eastern.tz, timezones.maybe_get_tz(tz))
|
||||
|
||||
@pytest.mark.parametrize("tzstr", ["US/Eastern", "dateutil/US/Eastern"])
|
||||
def test_tz_convert_unsorted(self, tzstr):
|
||||
dr = date_range("2012-03-09", freq="h", periods=100, tz="utc")
|
||||
dr = dr.tz_convert(tzstr)
|
||||
|
||||
result = dr[::-1].hour
|
||||
exp = dr.hour[::-1]
|
||||
tm.assert_almost_equal(result, exp)
|
||||
@@ -0,0 +1,402 @@
|
||||
from datetime import (
|
||||
datetime,
|
||||
timedelta,
|
||||
)
|
||||
|
||||
import dateutil.tz
|
||||
from dateutil.tz import gettz
|
||||
import numpy as np
|
||||
import pytest
|
||||
import pytz
|
||||
|
||||
from pandas import (
|
||||
DatetimeIndex,
|
||||
Timestamp,
|
||||
bdate_range,
|
||||
date_range,
|
||||
offsets,
|
||||
to_datetime,
|
||||
)
|
||||
import pandas._testing as tm
|
||||
|
||||
try:
|
||||
from zoneinfo import ZoneInfo
|
||||
except ImportError:
|
||||
# Cannot assign to a type [misc]
|
||||
ZoneInfo = None # type: ignore[misc, assignment]
|
||||
|
||||
|
||||
easts = [pytz.timezone("US/Eastern"), gettz("US/Eastern")]
|
||||
if ZoneInfo is not None:
|
||||
try:
|
||||
tz = ZoneInfo("US/Eastern")
|
||||
except KeyError:
|
||||
# no tzdata
|
||||
pass
|
||||
else:
|
||||
easts.append(tz)
|
||||
|
||||
|
||||
class TestTZLocalize:
|
||||
def test_tz_localize_invalidates_freq(self):
|
||||
# we only preserve freq in unambiguous cases
|
||||
|
||||
# if localized to US/Eastern, this crosses a DST transition
|
||||
dti = date_range("2014-03-08 23:00", "2014-03-09 09:00", freq="h")
|
||||
assert dti.freq == "h"
|
||||
|
||||
result = dti.tz_localize(None) # no-op
|
||||
assert result.freq == "h"
|
||||
|
||||
result = dti.tz_localize("UTC") # unambiguous freq preservation
|
||||
assert result.freq == "h"
|
||||
|
||||
result = dti.tz_localize("US/Eastern", nonexistent="shift_forward")
|
||||
assert result.freq is None
|
||||
assert result.inferred_freq is None # i.e. we are not _too_ strict here
|
||||
|
||||
# Case where we _can_ keep freq because we're length==1
|
||||
dti2 = dti[:1]
|
||||
result = dti2.tz_localize("US/Eastern")
|
||||
assert result.freq == "h"
|
||||
|
||||
def test_tz_localize_utc_copies(self, utc_fixture):
|
||||
# GH#46460
|
||||
times = ["2015-03-08 01:00", "2015-03-08 02:00", "2015-03-08 03:00"]
|
||||
index = DatetimeIndex(times)
|
||||
|
||||
res = index.tz_localize(utc_fixture)
|
||||
assert not tm.shares_memory(res, index)
|
||||
|
||||
res2 = index._data.tz_localize(utc_fixture)
|
||||
assert not tm.shares_memory(index._data, res2)
|
||||
|
||||
def test_dti_tz_localize_nonexistent_raise_coerce(self):
|
||||
# GH#13057
|
||||
times = ["2015-03-08 01:00", "2015-03-08 02:00", "2015-03-08 03:00"]
|
||||
index = DatetimeIndex(times)
|
||||
tz = "US/Eastern"
|
||||
with pytest.raises(pytz.NonExistentTimeError, match="|".join(times)):
|
||||
index.tz_localize(tz=tz)
|
||||
|
||||
with pytest.raises(pytz.NonExistentTimeError, match="|".join(times)):
|
||||
index.tz_localize(tz=tz, nonexistent="raise")
|
||||
|
||||
result = index.tz_localize(tz=tz, nonexistent="NaT")
|
||||
test_times = ["2015-03-08 01:00-05:00", "NaT", "2015-03-08 03:00-04:00"]
|
||||
dti = to_datetime(test_times, utc=True)
|
||||
expected = dti.tz_convert("US/Eastern")
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
@pytest.mark.parametrize("tz", easts)
|
||||
def test_dti_tz_localize_ambiguous_infer(self, tz):
|
||||
# November 6, 2011, fall back, repeat 2 AM hour
|
||||
# With no repeated hours, we cannot infer the transition
|
||||
dr = date_range(datetime(2011, 11, 6, 0), periods=5, freq=offsets.Hour())
|
||||
with pytest.raises(pytz.AmbiguousTimeError, match="Cannot infer dst time"):
|
||||
dr.tz_localize(tz)
|
||||
|
||||
@pytest.mark.parametrize("tz", easts)
|
||||
def test_dti_tz_localize_ambiguous_infer2(self, tz, unit):
|
||||
# With repeated hours, we can infer the transition
|
||||
dr = date_range(
|
||||
datetime(2011, 11, 6, 0), periods=5, freq=offsets.Hour(), tz=tz, unit=unit
|
||||
)
|
||||
times = [
|
||||
"11/06/2011 00:00",
|
||||
"11/06/2011 01:00",
|
||||
"11/06/2011 01:00",
|
||||
"11/06/2011 02:00",
|
||||
"11/06/2011 03:00",
|
||||
]
|
||||
di = DatetimeIndex(times).as_unit(unit)
|
||||
result = di.tz_localize(tz, ambiguous="infer")
|
||||
expected = dr._with_freq(None)
|
||||
tm.assert_index_equal(result, expected)
|
||||
result2 = DatetimeIndex(times, tz=tz, ambiguous="infer").as_unit(unit)
|
||||
tm.assert_index_equal(result2, expected)
|
||||
|
||||
@pytest.mark.parametrize("tz", easts)
|
||||
def test_dti_tz_localize_ambiguous_infer3(self, tz):
|
||||
# When there is no dst transition, nothing special happens
|
||||
dr = date_range(datetime(2011, 6, 1, 0), periods=10, freq=offsets.Hour())
|
||||
localized = dr.tz_localize(tz)
|
||||
localized_infer = dr.tz_localize(tz, ambiguous="infer")
|
||||
tm.assert_index_equal(localized, localized_infer)
|
||||
|
||||
@pytest.mark.parametrize("tz", easts)
|
||||
def test_dti_tz_localize_ambiguous_times(self, tz):
|
||||
# March 13, 2011, spring forward, skip from 2 AM to 3 AM
|
||||
dr = date_range(datetime(2011, 3, 13, 1, 30), periods=3, freq=offsets.Hour())
|
||||
with pytest.raises(pytz.NonExistentTimeError, match="2011-03-13 02:30:00"):
|
||||
dr.tz_localize(tz)
|
||||
|
||||
# after dst transition, it works
|
||||
dr = date_range(
|
||||
datetime(2011, 3, 13, 3, 30), periods=3, freq=offsets.Hour(), tz=tz
|
||||
)
|
||||
|
||||
# November 6, 2011, fall back, repeat 2 AM hour
|
||||
dr = date_range(datetime(2011, 11, 6, 1, 30), periods=3, freq=offsets.Hour())
|
||||
with pytest.raises(pytz.AmbiguousTimeError, match="Cannot infer dst time"):
|
||||
dr.tz_localize(tz)
|
||||
|
||||
# UTC is OK
|
||||
dr = date_range(
|
||||
datetime(2011, 3, 13), periods=48, freq=offsets.Minute(30), tz=pytz.utc
|
||||
)
|
||||
|
||||
@pytest.mark.parametrize("tzstr", ["US/Eastern", "dateutil/US/Eastern"])
|
||||
def test_dti_tz_localize_pass_dates_to_utc(self, tzstr):
|
||||
strdates = ["1/1/2012", "3/1/2012", "4/1/2012"]
|
||||
|
||||
idx = DatetimeIndex(strdates)
|
||||
conv = idx.tz_localize(tzstr)
|
||||
|
||||
fromdates = DatetimeIndex(strdates, tz=tzstr)
|
||||
|
||||
assert conv.tz == fromdates.tz
|
||||
tm.assert_numpy_array_equal(conv.values, fromdates.values)
|
||||
|
||||
@pytest.mark.parametrize("prefix", ["", "dateutil/"])
|
||||
def test_dti_tz_localize(self, prefix):
|
||||
tzstr = prefix + "US/Eastern"
|
||||
dti = date_range(start="1/1/2005", end="1/1/2005 0:00:30.256", freq="ms")
|
||||
dti2 = dti.tz_localize(tzstr)
|
||||
|
||||
dti_utc = date_range(
|
||||
start="1/1/2005 05:00", end="1/1/2005 5:00:30.256", freq="ms", tz="utc"
|
||||
)
|
||||
|
||||
tm.assert_numpy_array_equal(dti2.values, dti_utc.values)
|
||||
|
||||
dti3 = dti2.tz_convert(prefix + "US/Pacific")
|
||||
tm.assert_numpy_array_equal(dti3.values, dti_utc.values)
|
||||
|
||||
dti = date_range(start="11/6/2011 1:59", end="11/6/2011 2:00", freq="ms")
|
||||
with pytest.raises(pytz.AmbiguousTimeError, match="Cannot infer dst time"):
|
||||
dti.tz_localize(tzstr)
|
||||
|
||||
dti = date_range(start="3/13/2011 1:59", end="3/13/2011 2:00", freq="ms")
|
||||
with pytest.raises(pytz.NonExistentTimeError, match="2011-03-13 02:00:00"):
|
||||
dti.tz_localize(tzstr)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"tz",
|
||||
[
|
||||
"US/Eastern",
|
||||
"dateutil/US/Eastern",
|
||||
pytz.timezone("US/Eastern"),
|
||||
gettz("US/Eastern"),
|
||||
],
|
||||
)
|
||||
def test_dti_tz_localize_utc_conversion(self, tz):
|
||||
# Localizing to time zone should:
|
||||
# 1) check for DST ambiguities
|
||||
# 2) convert to UTC
|
||||
|
||||
rng = date_range("3/10/2012", "3/11/2012", freq="30min")
|
||||
|
||||
converted = rng.tz_localize(tz)
|
||||
expected_naive = rng + offsets.Hour(5)
|
||||
tm.assert_numpy_array_equal(converted.asi8, expected_naive.asi8)
|
||||
|
||||
# DST ambiguity, this should fail
|
||||
rng = date_range("3/11/2012", "3/12/2012", freq="30min")
|
||||
# Is this really how it should fail??
|
||||
with pytest.raises(pytz.NonExistentTimeError, match="2012-03-11 02:00:00"):
|
||||
rng.tz_localize(tz)
|
||||
|
||||
def test_dti_tz_localize_roundtrip(self, tz_aware_fixture):
|
||||
# note: this tz tests that a tz-naive index can be localized
|
||||
# and de-localized successfully, when there are no DST transitions
|
||||
# in the range.
|
||||
idx = date_range(start="2014-06-01", end="2014-08-30", freq="15min")
|
||||
tz = tz_aware_fixture
|
||||
localized = idx.tz_localize(tz)
|
||||
# can't localize a tz-aware object
|
||||
with pytest.raises(
|
||||
TypeError, match="Already tz-aware, use tz_convert to convert"
|
||||
):
|
||||
localized.tz_localize(tz)
|
||||
reset = localized.tz_localize(None)
|
||||
assert reset.tzinfo is None
|
||||
expected = idx._with_freq(None)
|
||||
tm.assert_index_equal(reset, expected)
|
||||
|
||||
def test_dti_tz_localize_naive(self):
|
||||
rng = date_range("1/1/2011", periods=100, freq="h")
|
||||
|
||||
conv = rng.tz_localize("US/Pacific")
|
||||
exp = date_range("1/1/2011", periods=100, freq="h", tz="US/Pacific")
|
||||
|
||||
tm.assert_index_equal(conv, exp._with_freq(None))
|
||||
|
||||
def test_dti_tz_localize_tzlocal(self):
|
||||
# GH#13583
|
||||
offset = dateutil.tz.tzlocal().utcoffset(datetime(2011, 1, 1))
|
||||
offset = int(offset.total_seconds() * 1000000000)
|
||||
|
||||
dti = date_range(start="2001-01-01", end="2001-03-01")
|
||||
dti2 = dti.tz_localize(dateutil.tz.tzlocal())
|
||||
tm.assert_numpy_array_equal(dti2.asi8 + offset, dti.asi8)
|
||||
|
||||
dti = date_range(start="2001-01-01", end="2001-03-01", tz=dateutil.tz.tzlocal())
|
||||
dti2 = dti.tz_localize(None)
|
||||
tm.assert_numpy_array_equal(dti2.asi8 - offset, dti.asi8)
|
||||
|
||||
@pytest.mark.parametrize("tz", easts)
|
||||
def test_dti_tz_localize_ambiguous_nat(self, tz):
|
||||
times = [
|
||||
"11/06/2011 00:00",
|
||||
"11/06/2011 01:00",
|
||||
"11/06/2011 01:00",
|
||||
"11/06/2011 02:00",
|
||||
"11/06/2011 03:00",
|
||||
]
|
||||
di = DatetimeIndex(times)
|
||||
localized = di.tz_localize(tz, ambiguous="NaT")
|
||||
|
||||
times = [
|
||||
"11/06/2011 00:00",
|
||||
np.nan,
|
||||
np.nan,
|
||||
"11/06/2011 02:00",
|
||||
"11/06/2011 03:00",
|
||||
]
|
||||
di_test = DatetimeIndex(times, tz="US/Eastern")
|
||||
|
||||
# left dtype is datetime64[ns, US/Eastern]
|
||||
# right is datetime64[ns, tzfile('/usr/share/zoneinfo/US/Eastern')]
|
||||
tm.assert_numpy_array_equal(di_test.values, localized.values)
|
||||
|
||||
@pytest.mark.parametrize("tz", easts)
|
||||
def test_dti_tz_localize_ambiguous_flags(self, tz, unit):
|
||||
# November 6, 2011, fall back, repeat 2 AM hour
|
||||
|
||||
# Pass in flags to determine right dst transition
|
||||
dr = date_range(
|
||||
datetime(2011, 11, 6, 0), periods=5, freq=offsets.Hour(), tz=tz, unit=unit
|
||||
)
|
||||
times = [
|
||||
"11/06/2011 00:00",
|
||||
"11/06/2011 01:00",
|
||||
"11/06/2011 01:00",
|
||||
"11/06/2011 02:00",
|
||||
"11/06/2011 03:00",
|
||||
]
|
||||
|
||||
# Test tz_localize
|
||||
di = DatetimeIndex(times).as_unit(unit)
|
||||
is_dst = [1, 1, 0, 0, 0]
|
||||
localized = di.tz_localize(tz, ambiguous=is_dst)
|
||||
expected = dr._with_freq(None)
|
||||
tm.assert_index_equal(expected, localized)
|
||||
|
||||
result = DatetimeIndex(times, tz=tz, ambiguous=is_dst).as_unit(unit)
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
localized = di.tz_localize(tz, ambiguous=np.array(is_dst))
|
||||
tm.assert_index_equal(dr, localized)
|
||||
|
||||
localized = di.tz_localize(tz, ambiguous=np.array(is_dst).astype("bool"))
|
||||
tm.assert_index_equal(dr, localized)
|
||||
|
||||
# Test constructor
|
||||
localized = DatetimeIndex(times, tz=tz, ambiguous=is_dst).as_unit(unit)
|
||||
tm.assert_index_equal(dr, localized)
|
||||
|
||||
# Test duplicate times where inferring the dst fails
|
||||
times += times
|
||||
di = DatetimeIndex(times).as_unit(unit)
|
||||
|
||||
# When the sizes are incompatible, make sure error is raised
|
||||
msg = "Length of ambiguous bool-array must be the same size as vals"
|
||||
with pytest.raises(Exception, match=msg):
|
||||
di.tz_localize(tz, ambiguous=is_dst)
|
||||
|
||||
# When sizes are compatible and there are repeats ('infer' won't work)
|
||||
is_dst = np.hstack((is_dst, is_dst))
|
||||
localized = di.tz_localize(tz, ambiguous=is_dst)
|
||||
dr = dr.append(dr)
|
||||
tm.assert_index_equal(dr, localized)
|
||||
|
||||
@pytest.mark.parametrize("tz", easts)
|
||||
def test_dti_tz_localize_ambiguous_flags2(self, tz, unit):
|
||||
# When there is no dst transition, nothing special happens
|
||||
dr = date_range(datetime(2011, 6, 1, 0), periods=10, freq=offsets.Hour())
|
||||
is_dst = np.array([1] * 10)
|
||||
localized = dr.tz_localize(tz)
|
||||
localized_is_dst = dr.tz_localize(tz, ambiguous=is_dst)
|
||||
tm.assert_index_equal(localized, localized_is_dst)
|
||||
|
||||
def test_dti_tz_localize_bdate_range(self):
|
||||
dr = bdate_range("1/1/2009", "1/1/2010")
|
||||
dr_utc = bdate_range("1/1/2009", "1/1/2010", tz=pytz.utc)
|
||||
localized = dr.tz_localize(pytz.utc)
|
||||
tm.assert_index_equal(dr_utc, localized)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"start_ts, tz, end_ts, shift",
|
||||
[
|
||||
["2015-03-29 02:20:00", "Europe/Warsaw", "2015-03-29 03:00:00", "forward"],
|
||||
[
|
||||
"2015-03-29 02:20:00",
|
||||
"Europe/Warsaw",
|
||||
"2015-03-29 01:59:59.999999999",
|
||||
"backward",
|
||||
],
|
||||
[
|
||||
"2015-03-29 02:20:00",
|
||||
"Europe/Warsaw",
|
||||
"2015-03-29 03:20:00",
|
||||
timedelta(hours=1),
|
||||
],
|
||||
[
|
||||
"2015-03-29 02:20:00",
|
||||
"Europe/Warsaw",
|
||||
"2015-03-29 01:20:00",
|
||||
timedelta(hours=-1),
|
||||
],
|
||||
["2018-03-11 02:33:00", "US/Pacific", "2018-03-11 03:00:00", "forward"],
|
||||
[
|
||||
"2018-03-11 02:33:00",
|
||||
"US/Pacific",
|
||||
"2018-03-11 01:59:59.999999999",
|
||||
"backward",
|
||||
],
|
||||
[
|
||||
"2018-03-11 02:33:00",
|
||||
"US/Pacific",
|
||||
"2018-03-11 03:33:00",
|
||||
timedelta(hours=1),
|
||||
],
|
||||
[
|
||||
"2018-03-11 02:33:00",
|
||||
"US/Pacific",
|
||||
"2018-03-11 01:33:00",
|
||||
timedelta(hours=-1),
|
||||
],
|
||||
],
|
||||
)
|
||||
@pytest.mark.parametrize("tz_type", ["", "dateutil/"])
|
||||
def test_dti_tz_localize_nonexistent_shift(
|
||||
self, start_ts, tz, end_ts, shift, tz_type, unit
|
||||
):
|
||||
# GH#8917
|
||||
tz = tz_type + tz
|
||||
if isinstance(shift, str):
|
||||
shift = "shift_" + shift
|
||||
dti = DatetimeIndex([Timestamp(start_ts)]).as_unit(unit)
|
||||
result = dti.tz_localize(tz, nonexistent=shift)
|
||||
expected = DatetimeIndex([Timestamp(end_ts)]).tz_localize(tz).as_unit(unit)
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
@pytest.mark.parametrize("offset", [-1, 1])
|
||||
def test_dti_tz_localize_nonexistent_shift_invalid(self, offset, warsaw):
|
||||
# GH#8917
|
||||
tz = warsaw
|
||||
dti = DatetimeIndex([Timestamp("2015-03-29 02:20:00")])
|
||||
msg = "The provided timedelta will relocalize on a nonexistent time"
|
||||
with pytest.raises(ValueError, match=msg):
|
||||
dti.tz_localize(tz, nonexistent=timedelta(seconds=offset))
|
||||
@@ -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),
|
||||
],
|
||||
dtype=index.dtype,
|
||||
)
|
||||
assert uniques.dtype == index.dtype # 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