332 lines
12 KiB
Python
332 lines
12 KiB
Python
|
import numpy as np
|
||
|
from datetime import datetime, timedelta
|
||
|
import pytest
|
||
|
|
||
|
import pandas as pd
|
||
|
import pandas.util.testing as tm
|
||
|
import pandas.core.indexes.period as period
|
||
|
from pandas.compat import lrange
|
||
|
|
||
|
from pandas._libs.tslibs.ccalendar import MONTHS
|
||
|
|
||
|
from pandas import (PeriodIndex, Period, DatetimeIndex, Timestamp, Series,
|
||
|
date_range, to_datetime, period_range)
|
||
|
|
||
|
|
||
|
class TestPeriodRepresentation(object):
|
||
|
"""
|
||
|
Wish to match NumPy units
|
||
|
"""
|
||
|
|
||
|
def _check_freq(self, freq, base_date):
|
||
|
rng = PeriodIndex(start=base_date, periods=10, freq=freq)
|
||
|
exp = np.arange(10, dtype=np.int64)
|
||
|
|
||
|
tm.assert_numpy_array_equal(rng.asi8, exp)
|
||
|
|
||
|
def test_annual(self):
|
||
|
self._check_freq('A', 1970)
|
||
|
|
||
|
def test_monthly(self):
|
||
|
self._check_freq('M', '1970-01')
|
||
|
|
||
|
@pytest.mark.parametrize('freq', ['W-THU', 'D', 'B', 'H', 'T',
|
||
|
'S', 'L', 'U', 'N'])
|
||
|
def test_freq(self, freq):
|
||
|
self._check_freq(freq, '1970-01-01')
|
||
|
|
||
|
def test_negone_ordinals(self):
|
||
|
freqs = ['A', 'M', 'Q', 'D', 'H', 'T', 'S']
|
||
|
|
||
|
period = Period(ordinal=-1, freq='D')
|
||
|
for freq in freqs:
|
||
|
repr(period.asfreq(freq))
|
||
|
|
||
|
for freq in freqs:
|
||
|
period = Period(ordinal=-1, freq=freq)
|
||
|
repr(period)
|
||
|
assert period.year == 1969
|
||
|
|
||
|
period = Period(ordinal=-1, freq='B')
|
||
|
repr(period)
|
||
|
period = Period(ordinal=-1, freq='W')
|
||
|
repr(period)
|
||
|
|
||
|
|
||
|
class TestPeriodIndex(object):
|
||
|
def test_to_timestamp(self):
|
||
|
index = PeriodIndex(freq='A', start='1/1/2001', end='12/1/2009')
|
||
|
series = Series(1, index=index, name='foo')
|
||
|
|
||
|
exp_index = date_range('1/1/2001', end='12/31/2009', freq='A-DEC')
|
||
|
result = series.to_timestamp(how='end')
|
||
|
tm.assert_index_equal(result.index, exp_index)
|
||
|
assert result.name == 'foo'
|
||
|
|
||
|
exp_index = date_range('1/1/2001', end='1/1/2009', freq='AS-JAN')
|
||
|
result = series.to_timestamp(how='start')
|
||
|
tm.assert_index_equal(result.index, exp_index)
|
||
|
|
||
|
def _get_with_delta(delta, freq='A-DEC'):
|
||
|
return date_range(to_datetime('1/1/2001') + delta,
|
||
|
to_datetime('12/31/2009') + delta, freq=freq)
|
||
|
|
||
|
delta = timedelta(hours=23)
|
||
|
result = series.to_timestamp('H', 'end')
|
||
|
exp_index = _get_with_delta(delta)
|
||
|
tm.assert_index_equal(result.index, exp_index)
|
||
|
|
||
|
delta = timedelta(hours=23, minutes=59)
|
||
|
result = series.to_timestamp('T', 'end')
|
||
|
exp_index = _get_with_delta(delta)
|
||
|
tm.assert_index_equal(result.index, exp_index)
|
||
|
|
||
|
result = series.to_timestamp('S', 'end')
|
||
|
delta = timedelta(hours=23, minutes=59, seconds=59)
|
||
|
exp_index = _get_with_delta(delta)
|
||
|
tm.assert_index_equal(result.index, exp_index)
|
||
|
|
||
|
index = PeriodIndex(freq='H', start='1/1/2001', end='1/2/2001')
|
||
|
series = Series(1, index=index, name='foo')
|
||
|
|
||
|
exp_index = date_range('1/1/2001 00:59:59', end='1/2/2001 00:59:59',
|
||
|
freq='H')
|
||
|
result = series.to_timestamp(how='end')
|
||
|
tm.assert_index_equal(result.index, exp_index)
|
||
|
assert result.name == 'foo'
|
||
|
|
||
|
def test_to_timestamp_repr_is_code(self):
|
||
|
zs = [Timestamp('99-04-17 00:00:00', tz='UTC'),
|
||
|
Timestamp('2001-04-17 00:00:00', tz='UTC'),
|
||
|
Timestamp('2001-04-17 00:00:00', tz='America/Los_Angeles'),
|
||
|
Timestamp('2001-04-17 00:00:00', tz=None)]
|
||
|
for z in zs:
|
||
|
assert eval(repr(z)) == z
|
||
|
|
||
|
def test_to_timestamp_to_period_astype(self):
|
||
|
idx = DatetimeIndex([pd.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)
|
||
|
|
||
|
def test_dti_to_period(self):
|
||
|
dti = DatetimeIndex(start='1/1/2005', end='12/1/2005', freq='M')
|
||
|
pi1 = dti.to_period()
|
||
|
pi2 = dti.to_period(freq='D')
|
||
|
pi3 = dti.to_period(freq='3D')
|
||
|
|
||
|
assert pi1[0] == Period('Jan 2005', freq='M')
|
||
|
assert pi2[0] == Period('1/31/2005', freq='D')
|
||
|
assert pi3[0] == Period('1/31/2005', freq='3D')
|
||
|
|
||
|
assert pi1[-1] == Period('Nov 2005', freq='M')
|
||
|
assert pi2[-1] == Period('11/30/2005', freq='D')
|
||
|
assert pi3[-1], Period('11/30/2005', freq='3D')
|
||
|
|
||
|
tm.assert_index_equal(pi1, period_range('1/1/2005', '11/1/2005',
|
||
|
freq='M'))
|
||
|
tm.assert_index_equal(pi2, period_range('1/1/2005', '11/1/2005',
|
||
|
freq='M').asfreq('D'))
|
||
|
tm.assert_index_equal(pi3, period_range('1/1/2005', '11/1/2005',
|
||
|
freq='M').asfreq('3D'))
|
||
|
|
||
|
@pytest.mark.parametrize('month', MONTHS)
|
||
|
def test_to_period_quarterly(self, month):
|
||
|
# make sure we can make the round trip
|
||
|
freq = 'Q-%s' % month
|
||
|
rng = period_range('1989Q3', '1991Q3', freq=freq)
|
||
|
stamps = rng.to_timestamp()
|
||
|
result = stamps.to_period(freq)
|
||
|
tm.assert_index_equal(rng, result)
|
||
|
|
||
|
@pytest.mark.parametrize('off', ['BQ', 'QS', 'BQS'])
|
||
|
def test_to_period_quarterlyish(self, off):
|
||
|
rng = date_range('01-Jan-2012', periods=8, freq=off)
|
||
|
prng = rng.to_period()
|
||
|
assert prng.freq == 'Q-DEC'
|
||
|
|
||
|
@pytest.mark.parametrize('off', ['BA', 'AS', 'BAS'])
|
||
|
def test_to_period_annualish(self, off):
|
||
|
rng = date_range('01-Jan-2012', periods=8, freq=off)
|
||
|
prng = rng.to_period()
|
||
|
assert prng.freq == 'A-DEC'
|
||
|
|
||
|
def test_to_period_monthish(self):
|
||
|
offsets = ['MS', 'BM']
|
||
|
for off in offsets:
|
||
|
rng = date_range('01-Jan-2012', periods=8, freq=off)
|
||
|
prng = rng.to_period()
|
||
|
assert prng.freq == 'M'
|
||
|
|
||
|
rng = date_range('01-Jan-2012', periods=8, freq='M')
|
||
|
prng = rng.to_period()
|
||
|
assert prng.freq == 'M'
|
||
|
|
||
|
msg = pd._libs.tslibs.frequencies._INVALID_FREQ_ERROR
|
||
|
with tm.assert_raises_regex(ValueError, msg):
|
||
|
date_range('01-Jan-2012', periods=8, freq='EOM')
|
||
|
|
||
|
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_combine_first(self):
|
||
|
# GH 3367
|
||
|
didx = pd.DatetimeIndex(start='1950-01-31', end='1950-07-31', freq='M')
|
||
|
pidx = pd.PeriodIndex(start=pd.Period('1950-1'),
|
||
|
end=pd.Period('1950-7'), freq='M')
|
||
|
# check to be consistent with DatetimeIndex
|
||
|
for idx in [didx, pidx]:
|
||
|
a = pd.Series([1, np.nan, np.nan, 4, 5, np.nan, 7], index=idx)
|
||
|
b = pd.Series([9, 9, 9, 9, 9, 9, 9], index=idx)
|
||
|
|
||
|
result = a.combine_first(b)
|
||
|
expected = pd.Series([1, 9, 9, 4, 5, 9, 7], index=idx,
|
||
|
dtype=np.float64)
|
||
|
tm.assert_series_equal(result, expected)
|
||
|
|
||
|
@pytest.mark.parametrize('freq', ['D', '2D'])
|
||
|
def test_searchsorted(self, freq):
|
||
|
pidx = pd.PeriodIndex(['2014-01-01', '2014-01-02', '2014-01-03',
|
||
|
'2014-01-04', '2014-01-05'], freq=freq)
|
||
|
|
||
|
p1 = pd.Period('2014-01-01', freq=freq)
|
||
|
assert pidx.searchsorted(p1) == 0
|
||
|
|
||
|
p2 = pd.Period('2014-01-04', freq=freq)
|
||
|
assert pidx.searchsorted(p2) == 3
|
||
|
|
||
|
msg = "Input has different freq=H from PeriodIndex"
|
||
|
with tm.assert_raises_regex(period.IncompatibleFrequency, msg):
|
||
|
pidx.searchsorted(pd.Period('2014-01-01', freq='H'))
|
||
|
|
||
|
msg = "Input has different freq=5D from PeriodIndex"
|
||
|
with tm.assert_raises_regex(period.IncompatibleFrequency, msg):
|
||
|
pidx.searchsorted(pd.Period('2014-01-01', freq='5D'))
|
||
|
|
||
|
with tm.assert_produces_warning(FutureWarning):
|
||
|
pidx.searchsorted(key=p2)
|
||
|
|
||
|
|
||
|
class TestPeriodIndexConversion(object):
|
||
|
def test_tolist(self):
|
||
|
index = PeriodIndex(freq='A', start='1/1/2001', end='12/1/2009')
|
||
|
rs = index.tolist()
|
||
|
for x in rs:
|
||
|
assert isinstance(x, Period)
|
||
|
|
||
|
recon = PeriodIndex(rs)
|
||
|
tm.assert_index_equal(index, recon)
|
||
|
|
||
|
def test_to_timestamp_pi_nat(self):
|
||
|
# GH#7228
|
||
|
index = PeriodIndex(['NaT', '2011-01', '2011-02'], freq='M',
|
||
|
name='idx')
|
||
|
|
||
|
result = index.to_timestamp('D')
|
||
|
expected = DatetimeIndex([pd.NaT, datetime(2011, 1, 1),
|
||
|
datetime(2011, 2, 1)], name='idx')
|
||
|
tm.assert_index_equal(result, expected)
|
||
|
assert result.name == 'idx'
|
||
|
|
||
|
result2 = result.to_period(freq='M')
|
||
|
tm.assert_index_equal(result2, index)
|
||
|
assert result2.name == 'idx'
|
||
|
|
||
|
result3 = result.to_period(freq='3M')
|
||
|
exp = PeriodIndex(['NaT', '2011-01', '2011-02'],
|
||
|
freq='3M', name='idx')
|
||
|
tm.assert_index_equal(result3, exp)
|
||
|
assert result3.freqstr == '3M'
|
||
|
|
||
|
msg = ('Frequency must be positive, because it'
|
||
|
' represents span: -2A')
|
||
|
with tm.assert_raises_regex(ValueError, msg):
|
||
|
result.to_period(freq='-2A')
|
||
|
|
||
|
def test_to_timestamp_preserve_name(self):
|
||
|
index = PeriodIndex(freq='A', start='1/1/2001', end='12/1/2009',
|
||
|
name='foo')
|
||
|
assert index.name == 'foo'
|
||
|
|
||
|
conv = index.to_timestamp('D')
|
||
|
assert conv.name == 'foo'
|
||
|
|
||
|
def test_to_timestamp_quarterly_bug(self):
|
||
|
years = np.arange(1960, 2000).repeat(4)
|
||
|
quarters = np.tile(lrange(1, 5), 40)
|
||
|
|
||
|
pindex = PeriodIndex(year=years, quarter=quarters)
|
||
|
|
||
|
stamps = pindex.to_timestamp('D', 'end')
|
||
|
expected = DatetimeIndex([x.to_timestamp('D', 'end') for x in pindex])
|
||
|
tm.assert_index_equal(stamps, expected)
|
||
|
|
||
|
def test_to_timestamp_pi_mult(self):
|
||
|
idx = PeriodIndex(['2011-01', 'NaT', '2011-02'],
|
||
|
freq='2M', name='idx')
|
||
|
|
||
|
result = idx.to_timestamp()
|
||
|
expected = DatetimeIndex(['2011-01-01', 'NaT', '2011-02-01'],
|
||
|
name='idx')
|
||
|
tm.assert_index_equal(result, expected)
|
||
|
|
||
|
result = idx.to_timestamp(how='E')
|
||
|
expected = DatetimeIndex(['2011-02-28', 'NaT', '2011-03-31'],
|
||
|
name='idx')
|
||
|
tm.assert_index_equal(result, expected)
|
||
|
|
||
|
def test_to_timestamp_pi_combined(self):
|
||
|
idx = PeriodIndex(start='2011', periods=2, freq='1D1H', name='idx')
|
||
|
|
||
|
result = idx.to_timestamp()
|
||
|
expected = DatetimeIndex(['2011-01-01 00:00', '2011-01-02 01:00'],
|
||
|
name='idx')
|
||
|
tm.assert_index_equal(result, expected)
|
||
|
|
||
|
result = idx.to_timestamp(how='E')
|
||
|
expected = DatetimeIndex(['2011-01-02 00:59:59',
|
||
|
'2011-01-03 01:59:59'],
|
||
|
name='idx')
|
||
|
tm.assert_index_equal(result, expected)
|
||
|
|
||
|
result = idx.to_timestamp(how='E', freq='H')
|
||
|
expected = DatetimeIndex(['2011-01-02 00:00', '2011-01-03 01:00'],
|
||
|
name='idx')
|
||
|
tm.assert_index_equal(result, expected)
|
||
|
|
||
|
def test_period_astype_to_timestamp(self):
|
||
|
pi = pd.PeriodIndex(['2011-01', '2011-02', '2011-03'], freq='M')
|
||
|
|
||
|
exp = pd.DatetimeIndex(['2011-01-01', '2011-02-01', '2011-03-01'])
|
||
|
tm.assert_index_equal(pi.astype('datetime64[ns]'), exp)
|
||
|
|
||
|
exp = pd.DatetimeIndex(['2011-01-31', '2011-02-28', '2011-03-31'])
|
||
|
tm.assert_index_equal(pi.astype('datetime64[ns]', how='end'), exp)
|
||
|
|
||
|
exp = pd.DatetimeIndex(['2011-01-01', '2011-02-01', '2011-03-01'],
|
||
|
tz='US/Eastern')
|
||
|
res = pi.astype('datetime64[ns, US/Eastern]')
|
||
|
tm.assert_index_equal(pi.astype('datetime64[ns, US/Eastern]'), exp)
|
||
|
|
||
|
exp = pd.DatetimeIndex(['2011-01-31', '2011-02-28', '2011-03-31'],
|
||
|
tz='US/Eastern')
|
||
|
res = pi.astype('datetime64[ns, US/Eastern]', how='end')
|
||
|
tm.assert_index_equal(res, exp)
|
||
|
|
||
|
def test_to_timestamp_1703(self):
|
||
|
index = period_range('1/1/2012', periods=4, freq='D')
|
||
|
|
||
|
result = index.to_timestamp()
|
||
|
assert result[0] == Timestamp('1/1/2012')
|