Updated script that can be controled by Nodejs web app
This commit is contained in:
@ -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,335 @@
|
||||
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):
|
||||
# GH 13149, GH 13209
|
||||
# verify that we are returning NaT as a string (and not unicode)
|
||||
|
||||
idx = DatetimeIndex(["2016-05-16", "NaT", NaT, np.nan])
|
||||
result = idx.astype(str)
|
||||
expected = Index(["2016-05-16", "NaT", "NaT", "NaT"], dtype=object)
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
def test_astype_str(self):
|
||||
# test astype string - #10442
|
||||
dti = date_range("2012-01-01", periods=4, name="test_name")
|
||||
result = dti.astype(str)
|
||||
expected = Index(
|
||||
["2012-01-01", "2012-01-02", "2012-01-03", "2012-01-04"],
|
||||
name="test_name",
|
||||
dtype=object,
|
||||
)
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
def test_astype_str_tz_and_name(self):
|
||||
# test astype string with tz and name
|
||||
dti = date_range("2012-01-01", periods=3, name="test_name", tz="US/Eastern")
|
||||
result = dti.astype(str)
|
||||
expected = Index(
|
||||
[
|
||||
"2012-01-01 00:00:00-05:00",
|
||||
"2012-01-02 00:00:00-05:00",
|
||||
"2012-01-03 00:00:00-05:00",
|
||||
],
|
||||
name="test_name",
|
||||
dtype=object,
|
||||
)
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
def test_astype_str_freq_and_name(self):
|
||||
# test astype string with freqH and name
|
||||
dti = date_range("1/1/2011", periods=3, freq="h", name="test_name")
|
||||
result = dti.astype(str)
|
||||
expected = Index(
|
||||
["2011-01-01 00:00:00", "2011-01-01 01:00:00", "2011-01-01 02:00:00"],
|
||||
name="test_name",
|
||||
dtype=object,
|
||||
)
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
def test_astype_str_freq_and_tz(self):
|
||||
# test astype string with freqH and timezone
|
||||
dti = date_range(
|
||||
"3/6/2012 00:00", periods=2, freq="h", tz="Europe/London", name="test_name"
|
||||
)
|
||||
result = dti.astype(str)
|
||||
expected = Index(
|
||||
["2012-03-06 00:00:00+00:00", "2012-03-06 01:00:00+00:00"],
|
||||
dtype=object,
|
||||
name="test_name",
|
||||
)
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
def test_astype_datetime64(self):
|
||||
# GH 13149, GH 13209
|
||||
idx = DatetimeIndex(
|
||||
["2016-05-16", "NaT", NaT, np.nan], 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