299 lines
13 KiB
Python
299 lines
13 KiB
Python
|
import locale
|
||
|
import calendar
|
||
|
|
||
|
import pytest
|
||
|
|
||
|
import numpy as np
|
||
|
import pandas as pd
|
||
|
import pandas.util.testing as tm
|
||
|
from pandas import (Index, DatetimeIndex, datetime, offsets,
|
||
|
date_range, Timestamp)
|
||
|
|
||
|
|
||
|
class TestTimeSeries(object):
|
||
|
|
||
|
def test_pass_datetimeindex_to_index(self):
|
||
|
# Bugs in #1396
|
||
|
rng = date_range('1/1/2000', '3/1/2000')
|
||
|
idx = Index(rng, dtype=object)
|
||
|
|
||
|
expected = Index(rng.to_pydatetime(), dtype=object)
|
||
|
|
||
|
tm.assert_numpy_array_equal(idx.values, expected.values)
|
||
|
|
||
|
def test_range_edges(self):
|
||
|
# GH 13672
|
||
|
idx = DatetimeIndex(start=Timestamp('1970-01-01 00:00:00.000000001'),
|
||
|
end=Timestamp('1970-01-01 00:00:00.000000004'),
|
||
|
freq='N')
|
||
|
exp = DatetimeIndex(['1970-01-01 00:00:00.000000001',
|
||
|
'1970-01-01 00:00:00.000000002',
|
||
|
'1970-01-01 00:00:00.000000003',
|
||
|
'1970-01-01 00:00:00.000000004'])
|
||
|
tm.assert_index_equal(idx, exp)
|
||
|
|
||
|
idx = DatetimeIndex(start=Timestamp('1970-01-01 00:00:00.000000004'),
|
||
|
end=Timestamp('1970-01-01 00:00:00.000000001'),
|
||
|
freq='N')
|
||
|
exp = DatetimeIndex([])
|
||
|
tm.assert_index_equal(idx, exp)
|
||
|
|
||
|
idx = DatetimeIndex(start=Timestamp('1970-01-01 00:00:00.000000001'),
|
||
|
end=Timestamp('1970-01-01 00:00:00.000000001'),
|
||
|
freq='N')
|
||
|
exp = DatetimeIndex(['1970-01-01 00:00:00.000000001'])
|
||
|
tm.assert_index_equal(idx, exp)
|
||
|
|
||
|
idx = DatetimeIndex(start=Timestamp('1970-01-01 00:00:00.000001'),
|
||
|
end=Timestamp('1970-01-01 00:00:00.000004'),
|
||
|
freq='U')
|
||
|
exp = DatetimeIndex(['1970-01-01 00:00:00.000001',
|
||
|
'1970-01-01 00:00:00.000002',
|
||
|
'1970-01-01 00:00:00.000003',
|
||
|
'1970-01-01 00:00:00.000004'])
|
||
|
tm.assert_index_equal(idx, exp)
|
||
|
|
||
|
idx = DatetimeIndex(start=Timestamp('1970-01-01 00:00:00.001'),
|
||
|
end=Timestamp('1970-01-01 00:00:00.004'),
|
||
|
freq='L')
|
||
|
exp = DatetimeIndex(['1970-01-01 00:00:00.001',
|
||
|
'1970-01-01 00:00:00.002',
|
||
|
'1970-01-01 00:00:00.003',
|
||
|
'1970-01-01 00:00:00.004'])
|
||
|
tm.assert_index_equal(idx, exp)
|
||
|
|
||
|
idx = DatetimeIndex(start=Timestamp('1970-01-01 00:00:01'),
|
||
|
end=Timestamp('1970-01-01 00:00:04'), freq='S')
|
||
|
exp = DatetimeIndex(['1970-01-01 00:00:01', '1970-01-01 00:00:02',
|
||
|
'1970-01-01 00:00:03', '1970-01-01 00:00:04'])
|
||
|
tm.assert_index_equal(idx, exp)
|
||
|
|
||
|
idx = DatetimeIndex(start=Timestamp('1970-01-01 00:01'),
|
||
|
end=Timestamp('1970-01-01 00:04'), freq='T')
|
||
|
exp = DatetimeIndex(['1970-01-01 00:01', '1970-01-01 00:02',
|
||
|
'1970-01-01 00:03', '1970-01-01 00:04'])
|
||
|
tm.assert_index_equal(idx, exp)
|
||
|
|
||
|
idx = DatetimeIndex(start=Timestamp('1970-01-01 01:00'),
|
||
|
end=Timestamp('1970-01-01 04:00'), freq='H')
|
||
|
exp = DatetimeIndex(['1970-01-01 01:00', '1970-01-01 02:00',
|
||
|
'1970-01-01 03:00', '1970-01-01 04:00'])
|
||
|
tm.assert_index_equal(idx, exp)
|
||
|
|
||
|
idx = DatetimeIndex(start=Timestamp('1970-01-01'),
|
||
|
end=Timestamp('1970-01-04'), freq='D')
|
||
|
exp = DatetimeIndex(['1970-01-01', '1970-01-02',
|
||
|
'1970-01-03', '1970-01-04'])
|
||
|
tm.assert_index_equal(idx, exp)
|
||
|
|
||
|
|
||
|
class TestDatetime64(object):
|
||
|
|
||
|
def test_datetimeindex_accessors(self):
|
||
|
dti_naive = DatetimeIndex(freq='D', start=datetime(1998, 1, 1),
|
||
|
periods=365)
|
||
|
# GH 13303
|
||
|
dti_tz = DatetimeIndex(freq='D', start=datetime(1998, 1, 1),
|
||
|
periods=365, tz='US/Eastern')
|
||
|
for dti in [dti_naive, dti_tz]:
|
||
|
|
||
|
assert dti.year[0] == 1998
|
||
|
assert dti.month[0] == 1
|
||
|
assert dti.day[0] == 1
|
||
|
assert dti.hour[0] == 0
|
||
|
assert dti.minute[0] == 0
|
||
|
assert dti.second[0] == 0
|
||
|
assert dti.microsecond[0] == 0
|
||
|
assert dti.dayofweek[0] == 3
|
||
|
|
||
|
assert dti.dayofyear[0] == 1
|
||
|
assert dti.dayofyear[120] == 121
|
||
|
|
||
|
assert dti.weekofyear[0] == 1
|
||
|
assert dti.weekofyear[120] == 18
|
||
|
|
||
|
assert dti.quarter[0] == 1
|
||
|
assert dti.quarter[120] == 2
|
||
|
|
||
|
assert dti.days_in_month[0] == 31
|
||
|
assert dti.days_in_month[90] == 30
|
||
|
|
||
|
assert dti.is_month_start[0]
|
||
|
assert not dti.is_month_start[1]
|
||
|
assert dti.is_month_start[31]
|
||
|
assert dti.is_quarter_start[0]
|
||
|
assert dti.is_quarter_start[90]
|
||
|
assert dti.is_year_start[0]
|
||
|
assert not dti.is_year_start[364]
|
||
|
assert not dti.is_month_end[0]
|
||
|
assert dti.is_month_end[30]
|
||
|
assert not dti.is_month_end[31]
|
||
|
assert dti.is_month_end[364]
|
||
|
assert not dti.is_quarter_end[0]
|
||
|
assert not dti.is_quarter_end[30]
|
||
|
assert dti.is_quarter_end[89]
|
||
|
assert dti.is_quarter_end[364]
|
||
|
assert not dti.is_year_end[0]
|
||
|
assert dti.is_year_end[364]
|
||
|
|
||
|
assert len(dti.year) == 365
|
||
|
assert len(dti.month) == 365
|
||
|
assert len(dti.day) == 365
|
||
|
assert len(dti.hour) == 365
|
||
|
assert len(dti.minute) == 365
|
||
|
assert len(dti.second) == 365
|
||
|
assert len(dti.microsecond) == 365
|
||
|
assert len(dti.dayofweek) == 365
|
||
|
assert len(dti.dayofyear) == 365
|
||
|
assert len(dti.weekofyear) == 365
|
||
|
assert len(dti.quarter) == 365
|
||
|
assert len(dti.is_month_start) == 365
|
||
|
assert len(dti.is_month_end) == 365
|
||
|
assert len(dti.is_quarter_start) == 365
|
||
|
assert len(dti.is_quarter_end) == 365
|
||
|
assert len(dti.is_year_start) == 365
|
||
|
assert len(dti.is_year_end) == 365
|
||
|
assert len(dti.weekday_name) == 365
|
||
|
|
||
|
dti.name = 'name'
|
||
|
|
||
|
# non boolean accessors -> return Index
|
||
|
for accessor in DatetimeIndex._field_ops:
|
||
|
res = getattr(dti, accessor)
|
||
|
assert len(res) == 365
|
||
|
assert isinstance(res, Index)
|
||
|
assert res.name == 'name'
|
||
|
|
||
|
# boolean accessors -> return array
|
||
|
for accessor in DatetimeIndex._bool_ops:
|
||
|
res = getattr(dti, accessor)
|
||
|
assert len(res) == 365
|
||
|
assert isinstance(res, np.ndarray)
|
||
|
|
||
|
# test boolean indexing
|
||
|
res = dti[dti.is_quarter_start]
|
||
|
exp = dti[[0, 90, 181, 273]]
|
||
|
tm.assert_index_equal(res, exp)
|
||
|
res = dti[dti.is_leap_year]
|
||
|
exp = DatetimeIndex([], freq='D', tz=dti.tz, name='name')
|
||
|
tm.assert_index_equal(res, exp)
|
||
|
|
||
|
dti = DatetimeIndex(freq='BQ-FEB', start=datetime(1998, 1, 1),
|
||
|
periods=4)
|
||
|
|
||
|
assert sum(dti.is_quarter_start) == 0
|
||
|
assert sum(dti.is_quarter_end) == 4
|
||
|
assert sum(dti.is_year_start) == 0
|
||
|
assert sum(dti.is_year_end) == 1
|
||
|
|
||
|
# Ensure is_start/end accessors throw ValueError for CustomBusinessDay,
|
||
|
# CBD requires np >= 1.7
|
||
|
bday_egypt = offsets.CustomBusinessDay(weekmask='Sun Mon Tue Wed Thu')
|
||
|
dti = date_range(datetime(2013, 4, 30), periods=5, freq=bday_egypt)
|
||
|
pytest.raises(ValueError, lambda: dti.is_month_start)
|
||
|
|
||
|
dti = DatetimeIndex(['2000-01-01', '2000-01-02', '2000-01-03'])
|
||
|
|
||
|
assert dti.is_month_start[0] == 1
|
||
|
|
||
|
tests = [
|
||
|
(Timestamp('2013-06-01', freq='M').is_month_start, 1),
|
||
|
(Timestamp('2013-06-01', freq='BM').is_month_start, 0),
|
||
|
(Timestamp('2013-06-03', freq='M').is_month_start, 0),
|
||
|
(Timestamp('2013-06-03', freq='BM').is_month_start, 1),
|
||
|
(Timestamp('2013-02-28', freq='Q-FEB').is_month_end, 1),
|
||
|
(Timestamp('2013-02-28', freq='Q-FEB').is_quarter_end, 1),
|
||
|
(Timestamp('2013-02-28', freq='Q-FEB').is_year_end, 1),
|
||
|
(Timestamp('2013-03-01', freq='Q-FEB').is_month_start, 1),
|
||
|
(Timestamp('2013-03-01', freq='Q-FEB').is_quarter_start, 1),
|
||
|
(Timestamp('2013-03-01', freq='Q-FEB').is_year_start, 1),
|
||
|
(Timestamp('2013-03-31', freq='QS-FEB').is_month_end, 1),
|
||
|
(Timestamp('2013-03-31', freq='QS-FEB').is_quarter_end, 0),
|
||
|
(Timestamp('2013-03-31', freq='QS-FEB').is_year_end, 0),
|
||
|
(Timestamp('2013-02-01', freq='QS-FEB').is_month_start, 1),
|
||
|
(Timestamp('2013-02-01', freq='QS-FEB').is_quarter_start, 1),
|
||
|
(Timestamp('2013-02-01', freq='QS-FEB').is_year_start, 1),
|
||
|
(Timestamp('2013-06-30', freq='BQ').is_month_end, 0),
|
||
|
(Timestamp('2013-06-30', freq='BQ').is_quarter_end, 0),
|
||
|
(Timestamp('2013-06-30', freq='BQ').is_year_end, 0),
|
||
|
(Timestamp('2013-06-28', freq='BQ').is_month_end, 1),
|
||
|
(Timestamp('2013-06-28', freq='BQ').is_quarter_end, 1),
|
||
|
(Timestamp('2013-06-28', freq='BQ').is_year_end, 0),
|
||
|
(Timestamp('2013-06-30', freq='BQS-APR').is_month_end, 0),
|
||
|
(Timestamp('2013-06-30', freq='BQS-APR').is_quarter_end, 0),
|
||
|
(Timestamp('2013-06-30', freq='BQS-APR').is_year_end, 0),
|
||
|
(Timestamp('2013-06-28', freq='BQS-APR').is_month_end, 1),
|
||
|
(Timestamp('2013-06-28', freq='BQS-APR').is_quarter_end, 1),
|
||
|
(Timestamp('2013-03-29', freq='BQS-APR').is_year_end, 1),
|
||
|
(Timestamp('2013-11-01', freq='AS-NOV').is_year_start, 1),
|
||
|
(Timestamp('2013-10-31', freq='AS-NOV').is_year_end, 1),
|
||
|
(Timestamp('2012-02-01').days_in_month, 29),
|
||
|
(Timestamp('2013-02-01').days_in_month, 28)]
|
||
|
|
||
|
for ts, value in tests:
|
||
|
assert ts == value
|
||
|
|
||
|
# GH 6538: Check that DatetimeIndex and its TimeStamp elements
|
||
|
# return the same weekofyear accessor close to new year w/ tz
|
||
|
dates = ["2013/12/29", "2013/12/30", "2013/12/31"]
|
||
|
dates = DatetimeIndex(dates, tz="Europe/Brussels")
|
||
|
expected = [52, 1, 1]
|
||
|
assert dates.weekofyear.tolist() == expected
|
||
|
assert [d.weekofyear for d in dates] == expected
|
||
|
|
||
|
# GH 12806
|
||
|
@pytest.mark.parametrize('time_locale', [
|
||
|
None] if tm.get_locales() is None else [None] + tm.get_locales())
|
||
|
def test_datetime_name_accessors(self, time_locale):
|
||
|
# Test Monday -> Sunday and January -> December, in that sequence
|
||
|
if time_locale is None:
|
||
|
# If the time_locale is None, day-name and month_name should
|
||
|
# return the english attributes
|
||
|
expected_days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday',
|
||
|
'Friday', 'Saturday', 'Sunday']
|
||
|
expected_months = ['January', 'February', 'March', 'April', 'May',
|
||
|
'June', 'July', 'August', 'September',
|
||
|
'October', 'November', 'December']
|
||
|
else:
|
||
|
with tm.set_locale(time_locale, locale.LC_TIME):
|
||
|
expected_days = calendar.day_name[:]
|
||
|
expected_months = calendar.month_name[1:]
|
||
|
|
||
|
# GH 11128
|
||
|
dti = DatetimeIndex(freq='D', start=datetime(1998, 1, 1),
|
||
|
periods=365)
|
||
|
english_days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday',
|
||
|
'Friday', 'Saturday', 'Sunday']
|
||
|
for day, name, eng_name in zip(range(4, 11),
|
||
|
expected_days,
|
||
|
english_days):
|
||
|
name = name.capitalize()
|
||
|
assert dti.weekday_name[day] == eng_name
|
||
|
assert dti.day_name(locale=time_locale)[day] == name
|
||
|
ts = Timestamp(datetime(2016, 4, day))
|
||
|
with tm.assert_produces_warning(FutureWarning,
|
||
|
check_stacklevel=False):
|
||
|
assert ts.weekday_name == eng_name
|
||
|
assert ts.day_name(locale=time_locale) == name
|
||
|
dti = dti.append(DatetimeIndex([pd.NaT]))
|
||
|
assert np.isnan(dti.day_name(locale=time_locale)[-1])
|
||
|
ts = Timestamp(pd.NaT)
|
||
|
assert np.isnan(ts.day_name(locale=time_locale))
|
||
|
|
||
|
# GH 12805
|
||
|
dti = DatetimeIndex(freq='M', start='2012', end='2013')
|
||
|
result = dti.month_name(locale=time_locale)
|
||
|
expected = Index([month.capitalize() for month in expected_months])
|
||
|
tm.assert_index_equal(result, expected)
|
||
|
for date, expected in zip(dti, expected_months):
|
||
|
result = date.month_name(locale=time_locale)
|
||
|
assert result == expected.capitalize()
|
||
|
dti = dti.append(DatetimeIndex([pd.NaT]))
|
||
|
assert np.isnan(dti.month_name(locale=time_locale)[-1])
|
||
|
|
||
|
def test_nanosecond_field(self):
|
||
|
dti = DatetimeIndex(np.arange(10))
|
||
|
|
||
|
tm.assert_index_equal(dti.nanosecond,
|
||
|
pd.Index(np.arange(10, dtype=np.int64)))
|