Skip to content

Commit 47e3aec

Browse files
jbrockmendelPingviinituutti
authored andcommitted
Implement TimedeltaArray._from_sequence (pandas-dev#23953)
1 parent 55bf86c commit 47e3aec

File tree

4 files changed

+30
-38
lines changed

4 files changed

+30
-38
lines changed

pandas/core/arrays/timedeltas.py

+15-9
Original file line numberDiff line numberDiff line change
@@ -163,11 +163,17 @@ def _simple_new(cls, values, freq=None, dtype=_TD_DTYPE):
163163
return result
164164

165165
def __new__(cls, values, freq=None, dtype=_TD_DTYPE, copy=False):
166+
return cls._from_sequence(values, freq=freq, dtype=dtype, copy=copy)
167+
168+
@classmethod
169+
def _from_sequence(cls, data, freq=None, unit=None,
170+
dtype=_TD_DTYPE, copy=False):
171+
if dtype != _TD_DTYPE:
172+
raise ValueError("Only timedelta64[ns] dtype is valid.")
166173

167174
freq, freq_infer = dtl.maybe_infer_freq(freq)
168175

169-
values, inferred_freq = sequence_to_td64ns(
170-
values, copy=copy, unit=None)
176+
data, inferred_freq = sequence_to_td64ns(data, copy=copy, unit=unit)
171177
if inferred_freq is not None:
172178
if freq is not None and freq != inferred_freq:
173179
raise ValueError('Inferred frequency {inferred} from passed '
@@ -179,13 +185,13 @@ def __new__(cls, values, freq=None, dtype=_TD_DTYPE, copy=False):
179185
freq = inferred_freq
180186
freq_infer = False
181187

182-
result = cls._simple_new(values, freq=freq)
183-
# check that we are matching freqs
184-
if inferred_freq is None and len(result) > 0:
185-
if freq is not None and not freq_infer:
186-
cls._validate_frequency(result, freq)
188+
result = cls._simple_new(data, freq=freq)
189+
190+
if inferred_freq is None and freq is not None:
191+
# this condition precludes `freq_infer`
192+
cls._validate_frequency(result, freq)
187193

188-
if freq_infer:
194+
elif freq_infer:
189195
result.freq = to_offset(result.inferred_freq)
190196

191197
return result
@@ -666,7 +672,7 @@ def sequence_to_td64ns(data, copy=False, unit="ns", errors="raise"):
666672
warnings.warn("Passing datetime64-dtype data to TimedeltaIndex is "
667673
"deprecated, will raise a TypeError in a future "
668674
"version",
669-
FutureWarning, stacklevel=3)
675+
FutureWarning, stacklevel=4)
670676
data = ensure_int64(data).view(_TD_DTYPE)
671677

672678
else:

pandas/core/indexes/timedeltas.py

+7-28
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@
1717

1818
from pandas.core.arrays import datetimelike as dtl
1919
from pandas.core.arrays.timedeltas import (
20-
TimedeltaArrayMixin as TimedeltaArray, _is_convertible_to_td, _to_m8,
21-
sequence_to_td64ns)
20+
TimedeltaArrayMixin as TimedeltaArray, _is_convertible_to_td, _to_m8)
2221
from pandas.core.base import _shared_docs
2322
import pandas.core.common as com
2423
from pandas.core.indexes.base import Index, _index_shared_docs
@@ -132,7 +131,7 @@ def _join_i8_wrapper(joinf, **kwargs):
132131
# Constructors
133132

134133
def __new__(cls, data=None, unit=None, freq=None, start=None, end=None,
135-
periods=None, closed=None, dtype=None, copy=False,
134+
periods=None, closed=None, dtype=_TD_DTYPE, copy=False,
136135
name=None, verify_integrity=None):
137136

138137
if verify_integrity is not None:
@@ -142,9 +141,8 @@ def __new__(cls, data=None, unit=None, freq=None, start=None, end=None,
142141
else:
143142
verify_integrity = True
144143

145-
freq, freq_infer = dtl.maybe_infer_freq(freq)
146-
147144
if data is None:
145+
freq, freq_infer = dtl.maybe_infer_freq(freq)
148146
warnings.warn("Creating a TimedeltaIndex by passing range "
149147
"endpoints is deprecated. Use "
150148
"`pandas.timedelta_range` instead.",
@@ -167,29 +165,10 @@ def __new__(cls, data=None, unit=None, freq=None, start=None, end=None,
167165

168166
# - Cases checked above all return/raise before reaching here - #
169167

170-
data, inferred_freq = sequence_to_td64ns(data, copy=copy, unit=unit)
171-
if inferred_freq is not None:
172-
if freq is not None and freq != inferred_freq:
173-
raise ValueError('Inferred frequency {inferred} from passed '
174-
'values does not conform to passed frequency '
175-
'{passed}'
176-
.format(inferred=inferred_freq,
177-
passed=freq.freqstr))
178-
elif freq_infer:
179-
freq = inferred_freq
180-
freq_infer = False
181-
verify_integrity = False
182-
183-
subarr = cls._simple_new(data, name=name, freq=freq)
184-
# check that we are matching freqs
185-
if verify_integrity and len(subarr) > 0:
186-
if freq is not None and not freq_infer:
187-
cls._validate_frequency(subarr, freq)
188-
189-
if freq_infer:
190-
subarr.freq = to_offset(subarr.inferred_freq)
191-
192-
return subarr
168+
result = cls._from_sequence(data, freq=freq, unit=unit,
169+
dtype=dtype, copy=copy)
170+
result.name = name
171+
return result
193172

194173
@classmethod
195174
def _simple_new(cls, values, name=None, freq=None, dtype=_TD_DTYPE):

pandas/tests/arrays/test_timedeltas.py

+7
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
11
# -*- coding: utf-8 -*-
22

33
import numpy as np
4+
import pytest
45

56
import pandas as pd
67
from pandas.core.arrays import TimedeltaArrayMixin as TimedeltaArray
78
import pandas.util.testing as tm
89

910

1011
class TestTimedeltaArray(object):
12+
def test_from_sequence_dtype(self):
13+
msg = r"Only timedelta64\[ns\] dtype is valid"
14+
with pytest.raises(ValueError, match=msg):
15+
TimedeltaArray._from_sequence([], dtype=object)
16+
with pytest.raises(ValueError, match=msg):
17+
TimedeltaArray([], dtype=object)
1118

1219
def test_abs(self):
1320
vals = np.array([-3600 * 10**9, 'NaT', 7200 * 10**9], dtype='m8[ns]')

pandas/tests/dtypes/test_inference.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1163,7 +1163,7 @@ def test_is_timedelta(self):
11631163
assert not is_timedelta64_ns_dtype('timedelta64')
11641164
assert is_timedelta64_ns_dtype('timedelta64[ns]')
11651165

1166-
tdi = TimedeltaIndex([1e14, 2e14], dtype='timedelta64')
1166+
tdi = TimedeltaIndex([1e14, 2e14], dtype='timedelta64[ns]')
11671167
assert is_timedelta64_dtype(tdi)
11681168
assert is_timedelta64_ns_dtype(tdi)
11691169
assert is_timedelta64_ns_dtype(tdi.astype('timedelta64[ns]'))

0 commit comments

Comments
 (0)