Skip to content

Separate out non-scalar tests from scalar tests; move to ?? in follow-up #18142

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 16 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions pandas/tests/frame/test_timestamps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
""" test DataFrame-boxed versions of the scalar Timestamp """
from datetime import datetime

import numpy as np

import pandas.util.testing as tm
from pandas.tseries import offsets

from pandas.compat import lrange
from pandas import (Timestamp, date_range,
Series, DataFrame, DatetimeIndex)


class TestDataFrameTimestamps(object):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so we already have test_timeseries.py, is there a reason you are creating a new module here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really, will move.

def test_series_map_box_timestamps(self):
# GH#2689, GH#2627
s = Series(date_range('1/1/2000', periods=10))

def f(x):
return (x.hour, x.day, x.month)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be in series

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It relies on DataFrame (although the whole thing is a smoke test). Maybe rename test_series_map_box_timestamps--> test_map_box_timestamps?


# it works!
s.map(f)
s.apply(f)
DataFrame(s).applymap(f)

def test_frame_setitem_timestamp(self):
# GH#2155
columns = DatetimeIndex(start='1/1/2012', end='2/1/2012',
freq=offsets.BDay())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

series

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

? the columns above are explicitly passed to the DataFrame constructor...

index = lrange(10)
data = DataFrame(columns=columns, index=index)
t = datetime(2012, 11, 1)
ts = Timestamp(t)
data[ts] = np.nan # works

def test_to_html_timestamp(self):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prob go with other html output tests (which I think are in formats)

rng = date_range('2000-01-01', periods=10)
df = DataFrame(np.random.randn(10, 4), index=rng)

result = df.to_html()
assert '2000-01-01' in result

def test_compare_invalid(self):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this has nothing to do with frame

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree it looks like an unnecessary use of the constructor, am assuming that someone had a reason.

# GH 8058
df = DataFrame(np.random.randn(5, 2))
a = df[0]
b = Series(np.random.randn(5))
b.name = Timestamp('2000-01-01')
tm.assert_series_equal(a / b, 1 / (b / a))
127 changes: 127 additions & 0 deletions pandas/tests/indexes/datetimes/test_datetime.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
import pytest

import pytz
import numpy as np
from datetime import date, timedelta, time

import dateutil
import pandas as pd
import pandas.util.testing as tm
from pandas._libs import period as libperiod
from pandas.compat import lrange
from pandas.compat.numpy import np_datetime64_compat
from pandas import (DatetimeIndex, Index, date_range, DataFrame,
Timestamp, datetime, offsets)
from pandas.tseries.frequencies import (RESO_DAY, RESO_HR, RESO_MIN, RESO_US,
RESO_MS, RESO_SEC)

from pandas.util.testing import assert_almost_equal

Expand Down Expand Up @@ -664,3 +668,126 @@ def test_factorize_dst(self):
arr, res = obj.factorize()
tm.assert_numpy_array_equal(arr, np.arange(12, dtype=np.intp))
tm.assert_index_equal(res, idx)


class TestDatetimeIndexVectorizedTimestamp(object):
def test_timestamp_date_out_of_range(self):
# see gh-1475
pytest.raises(ValueError, DatetimeIndex, ['1400-01-01'])
pytest.raises(ValueError, DatetimeIndex, [datetime(1400, 1, 1)])

def test_timestamp_fields(self):
# extra fields from DatetimeIndex like quarter and week
idx = tm.makeDateIndex(100)

fields = ['dayofweek', 'dayofyear', 'week', 'weekofyear', 'quarter',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these are in ops or misc

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moving this class to test_ops. Keeping it together because I like the fact that it is reasonably circumscribed as "vectorized versions of Timestamp operations", i.e. except for the DatetimeIndex constructor, most of what is being tested is in tslibs.

'days_in_month', 'is_month_start', 'is_month_end',
'is_quarter_start', 'is_quarter_end', 'is_year_start',
'is_year_end', 'weekday_name']
for f in fields:
expected = getattr(idx, f)[-1]
result = getattr(Timestamp(idx[-1]), f)
assert result == expected

assert idx.freq == Timestamp(idx[-1], idx.freq).freq
assert idx.freqstr == Timestamp(idx[-1], idx.freq).freqstr

def test_round(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 = date_range('20130101 09:10:11',
periods=5).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)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ops


result = dti.round('s')
tm.assert_index_equal(result, dti)

# invalid
for freq in ['Y', 'M', 'foobar']:
pytest.raises(ValueError, lambda: dti.round(freq))

def test_tz_localize_ambiguous(self):
ts = Timestamp('2014-11-02 01:00')
ts_dst = ts.tz_localize('US/Eastern', ambiguous=True)
ts_no_dst = ts.tz_localize('US/Eastern', ambiguous=False)

rng = date_range('2014-11-02', periods=3, freq='H', tz='US/Eastern')
assert rng[1] == ts_dst
assert rng[2] == ts_no_dst
pytest.raises(ValueError, ts.tz_localize, 'US/Eastern',
ambiguous='infer')

def test_resolution(self):
for freq, expected in zip(['A', 'Q', 'M', 'D', 'H', 'T',
'S', 'L', 'U'],
[RESO_DAY, RESO_DAY,
RESO_DAY, RESO_DAY,
RESO_HR, RESO_MIN,
RESO_SEC, RESO_MS,
RESO_US]):
for tz in [None, 'Asia/Tokyo', 'US/Eastern',
'dateutil/US/Eastern']:
idx = date_range(start='2013-04-01', periods=30, freq=freq,
tz=tz)
result = libperiod.resolution(idx.asi8, idx.tz)
assert result == expected


class TestTimestampEquivDateRange(object):
# Older tests in TestTimeSeries constructed their `stamp` objects
# using `date_range` instead of the `Timestamp` constructor.
# TestTimestampEquivDateRange checks that these are equivalent in the
# pertinent cases.

def test_date_range_timestamp_equiv(self):
rng = date_range('20090415', '20090519', tz='US/Eastern')
stamp = rng[0]

ts = Timestamp('20090415', tz='US/Eastern', freq='D')
assert ts == stamp

def test_date_range_timestamp_equiv_dateutil(self):
rng = date_range('20090415', '20090519', tz='dateutil/US/Eastern')
stamp = rng[0]

ts = Timestamp('20090415', tz='dateutil/US/Eastern', freq='D')
assert ts == stamp

def test_date_range_timestamp_equiv_explicit_pytz(self):
rng = date_range('20090415', '20090519',
tz=pytz.timezone('US/Eastern'))
stamp = rng[0]

ts = Timestamp('20090415', tz=pytz.timezone('US/Eastern'), freq='D')
assert ts == stamp

def test_date_range_timestamp_equiv_explicit_dateutil(self):
tm._skip_if_windows_python_3()
from pandas._libs.tslibs.timezones import dateutil_gettz as gettz

rng = date_range('20090415', '20090519', tz=gettz('US/Eastern'))
stamp = rng[0]

ts = Timestamp('20090415', tz=gettz('US/Eastern'), freq='D')
assert ts == stamp

def test_date_range_timestamp_equiv_from_datetime_instance(self):
datetime_instance = datetime(2014, 3, 4)
# build a timestamp with a frequency, since then it supports
# addition/subtraction of integers
timestamp_instance = date_range(datetime_instance, periods=1,
freq='D')[0]

ts = Timestamp(datetime_instance, freq='D')
assert ts == timestamp_instance

def test_date_range_timestamp_equiv_preserve_frequency(self):
timestamp_instance = date_range('2014-03-05', periods=1, freq='D')[0]
ts = Timestamp('2014-03-05', freq='D')

assert timestamp_instance == ts
15 changes: 15 additions & 0 deletions pandas/tests/indexes/datetimes/test_partial_slicing.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,21 @@


class TestSlicing(object):
def test_dti_slicing(self):
dti = DatetimeIndex(start='1/1/2005', end='12/1/2005', freq='M')
dti2 = dti[[1, 3, 5]]

v1 = dti2[0]
v2 = dti2[1]
v3 = dti2[2]

assert v1 == Timestamp('2/28/2005')
assert v2 == Timestamp('4/30/2005')
assert v3 == Timestamp('6/30/2005')

# don't carry freq through irregular slicing
assert dti2.freq is None

def test_slice_keeps_name(self):
# GH4226
st = pd.Timestamp('2013-07-01 00:00:00', tz='America/Los_Angeles')
Expand Down
101 changes: 101 additions & 0 deletions pandas/tests/indexes/timedeltas/test_timedelta.py
Original file line number Diff line number Diff line change
Expand Up @@ -508,3 +508,104 @@ def test_series_box_timedelta(self):
s = Series(rng)
assert isinstance(s[1], Timedelta)
assert isinstance(s.iat[2], Timedelta)


Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make a note to parametrize this

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not clear what "this" is in context.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is the calling of testit, simple enough should be to paramerize the units which its iterating

class TestTimedeltaIndexVectorizedTimedelta(object):
def test_contains(self):
# Checking for any NaT-like objects
# GH 13603
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is an indexing test

td = pd.to_timedelta(range(5), unit='d') + pd.offsets.Hour(1)
for v in [pd.NaT, None, float('nan'), np.nan]:
assert not (v in td)

td = pd.to_timedelta([pd.NaT])
for v in [pd.NaT, None, float('nan'), np.nan]:
assert (v in td)

def test_nat_converters(self):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we have a section on nat tests

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are many of these spread around. I really think we should focus for now on getting non-scalar tests out of scalar and recognize that this is a more-than-one-PR task.


def testit(unit, transform):
# array
result = pd.to_timedelta(np.arange(5), unit=unit)
expected = TimedeltaIndex([np.timedelta64(i, transform(unit))
for i in np.arange(5).tolist()])
tm.assert_index_equal(result, expected)

# scalar
result = pd.to_timedelta(2, unit=unit)
expected = Timedelta(np.timedelta64(2, transform(unit)).astype(
'timedelta64[ns]'))
assert result == expected

# validate all units
# GH 6855
for unit in ['Y', 'M', 'W', 'D', 'y', 'w', 'd']:
testit(unit, lambda x: x.upper())
for unit in ['days', 'day', 'Day', 'Days']:
testit(unit, lambda x: 'D')
for unit in ['h', 'm', 's', 'ms', 'us', 'ns', 'H', 'S', 'MS', 'US',
'NS']:
testit(unit, lambda x: x.lower())

# offsets

# m
testit('T', lambda x: 'm')

# ms
testit('L', lambda x: 'ms')

def test_timedelta_hash_equality(self):
# GH 11129
tds = timedelta_range('1 second', periods=20)
assert all(hash(td) == hash(td.to_pytimedelta()) for td in tds)

def test_round(self):
t1 = timedelta_range('1 days', periods=3, freq='1 min 2 s 3 us')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move to like tests

t2 = -1 * t1
t1a = timedelta_range('1 days', periods=3, freq='1 min 2 s')
t1c = pd.TimedeltaIndex([1, 1, 1], unit='D')

# note that negative times round DOWN! so don't give whole numbers
for (freq, s1, s2) in [('N', t1, t2),
('U', t1, t2),
('L', t1a,
TimedeltaIndex(['-1 days +00:00:00',
'-2 days +23:58:58',
'-2 days +23:57:56'],
dtype='timedelta64[ns]',
freq=None)
),
('S', t1a,
TimedeltaIndex(['-1 days +00:00:00',
'-2 days +23:58:58',
'-2 days +23:57:56'],
dtype='timedelta64[ns]',
freq=None)
),
('12T', t1c,
TimedeltaIndex(['-1 days',
'-1 days',
'-1 days'],
dtype='timedelta64[ns]',
freq=None)
),
('H', t1c,
TimedeltaIndex(['-1 days',
'-1 days',
'-1 days'],
dtype='timedelta64[ns]',
freq=None)
),
('d', t1c,
pd.TimedeltaIndex([-1, -1, -1], unit='D')
)]:

r1 = t1.round(freq)
tm.assert_index_equal(r1, s1)
r2 = t2.round(freq)
tm.assert_index_equal(r2, s2)

# invalid
for freq in ['Y', 'M', 'foobar']:
pytest.raises(ValueError, lambda: t1.round(freq))
Loading