Skip to content

Commit a9034c7

Browse files
committed
merge with master
2 parents 43601bc + bfa29f1 commit a9034c7

17 files changed

+78
-143
lines changed

doc/source/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@
195195

196196
# The theme to use for HTML and HTML Help pages. Major themes that come with
197197
# Sphinx are currently 'default' and 'sphinxdoc'.
198-
html_theme = "pandas_sphinx_theme"
198+
html_theme = "pydata_sphinx_theme"
199199

200200
# The style sheet to use for HTML and HTML Help pages. A file of that name
201201
# must exist either in Sphinx' static/ path, or in one of the custom paths

environment.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,5 +104,5 @@ dependencies:
104104
- pyreadstat # pandas.read_spss
105105
- tabulate>=0.8.3 # DataFrame.to_markdown
106106
- pip:
107-
- git+https://github.com/pandas-dev/pandas-sphinx-theme.git@master
107+
- git+https://github.com/pandas-dev/pydata-sphinx-theme.git@master
108108
- git+https://github.com/numpy/numpydoc

pandas/_libs/hashtable_class_helper.pxi.in

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ cdef class StringVector:
196196

197197
append_data_string(self.data, x)
198198

199-
cdef extend(self, ndarray[:] x):
199+
cdef extend(self, ndarray[object] x):
200200
for i in range(len(x)):
201201
self.append(x[i])
202202

@@ -241,7 +241,7 @@ cdef class ObjectVector:
241241
self.external_view_exists = True
242242
return self.ao
243243

244-
cdef extend(self, ndarray[:] x):
244+
cdef extend(self, ndarray[object] x):
245245
for i in range(len(x)):
246246
self.append(x[i])
247247

pandas/_libs/internals.pyx

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -378,25 +378,23 @@ def get_blkno_indexers(int64_t[:] blknos, bint group=True):
378378

379379
object blkno
380380
object group_dict = defaultdict(list)
381-
int64_t[:] res_view
382381

383382
n = blknos.shape[0]
384-
385-
if n == 0:
386-
return
387-
383+
result = list()
388384
start = 0
389385
cur_blkno = blknos[start]
390386

391-
if group is False:
387+
if n == 0:
388+
pass
389+
elif group is False:
392390
for i in range(1, n):
393391
if blknos[i] != cur_blkno:
394-
yield cur_blkno, slice(start, i)
392+
result.append((cur_blkno, slice(start, i)))
395393

396394
start = i
397395
cur_blkno = blknos[i]
398396

399-
yield cur_blkno, slice(start, n)
397+
result.append((cur_blkno, slice(start, n)))
400398
else:
401399
for i in range(1, n):
402400
if blknos[i] != cur_blkno:
@@ -409,19 +407,20 @@ def get_blkno_indexers(int64_t[:] blknos, bint group=True):
409407

410408
for blkno, slices in group_dict.items():
411409
if len(slices) == 1:
412-
yield blkno, slice(slices[0][0], slices[0][1])
410+
result.append((blkno, slice(slices[0][0], slices[0][1])))
413411
else:
414412
tot_len = sum(stop - start for start, stop in slices)
415-
result = np.empty(tot_len, dtype=np.int64)
416-
res_view = result
413+
arr = np.empty(tot_len, dtype=np.int64)
417414

418415
i = 0
419416
for start, stop in slices:
420417
for diff in range(start, stop):
421-
res_view[i] = diff
418+
arr[i] = diff
422419
i += 1
423420

424-
yield blkno, result
421+
result.append((blkno, arr))
422+
423+
return result
425424

426425

427426
def get_blkno_placements(blknos, group: bool = True):

pandas/_libs/parsers.pyx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -792,7 +792,6 @@ cdef class TextReader:
792792
self._tokenize_rows(1)
793793

794794
header = [ self.names ]
795-
data_line = 0
796795

797796
if self.parser.lines < 1:
798797
field_count = len(header[0])

pandas/_libs/src/ujson/python/date_conversions.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ npy_datetime NpyDateTimeToEpoch(npy_datetime dt, NPY_DATETIMEUNIT base) {
6767
}
6868

6969
/* Convert PyDatetime To ISO C-string. mutates len */
70-
char *PyDateTimeToIso(PyDateTime_Date *obj, NPY_DATETIMEUNIT base,
70+
char *PyDateTimeToIso(PyObject *obj, NPY_DATETIMEUNIT base,
7171
size_t *len) {
7272
npy_datetimestruct dts;
7373
int ret;
@@ -98,7 +98,7 @@ char *PyDateTimeToIso(PyDateTime_Date *obj, NPY_DATETIMEUNIT base,
9898
return result;
9999
}
100100

101-
npy_datetime PyDateTimeToEpoch(PyDateTime_Date *dt, NPY_DATETIMEUNIT base) {
101+
npy_datetime PyDateTimeToEpoch(PyObject *dt, NPY_DATETIMEUNIT base) {
102102
npy_datetimestruct dts;
103103
int ret;
104104

pandas/_libs/src/ujson/python/date_conversions.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
#define PY_SSIZE_T_CLEAN
55
#include <Python.h>
66
#include <numpy/ndarraytypes.h>
7-
#include "datetime.h"
87

98
// Scales value inplace from nanosecond resolution to unit resolution
109
int scaleNanosecToUnit(npy_int64 *value, NPY_DATETIMEUNIT unit);
@@ -23,10 +22,10 @@ npy_datetime NpyDateTimeToEpoch(npy_datetime dt, NPY_DATETIMEUNIT base);
2322
// up to precision `base` e.g. base="s" yields 2020-01-03T00:00:00Z
2423
// while base="ns" yields "2020-01-01T00:00:00.000000000Z"
2524
// len is mutated to save the length of the returned string
26-
char *PyDateTimeToIso(PyDateTime_Date *obj, NPY_DATETIMEUNIT base, size_t *len);
25+
char *PyDateTimeToIso(PyObject *obj, NPY_DATETIMEUNIT base, size_t *len);
2726

2827
// Convert a Python Date/Datetime to Unix epoch with resolution base
29-
npy_datetime PyDateTimeToEpoch(PyDateTime_Date *dt, NPY_DATETIMEUNIT base);
28+
npy_datetime PyDateTimeToEpoch(PyObject *dt, NPY_DATETIMEUNIT base);
3029

3130
char *int64ToIsoDuration(int64_t value, size_t *len);
3231

pandas/_libs/src/ujson/python/objToJSON.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1451,7 +1451,7 @@ char **NpyArr_encodeLabels(PyArrayObject *labels, PyObjectEncoder *enc,
14511451
} else {
14521452
// datetime.* objects don't follow above rules
14531453
nanosecVal =
1454-
PyDateTimeToEpoch((PyDateTime_Date *)item, NPY_FR_ns);
1454+
PyDateTimeToEpoch(item, NPY_FR_ns);
14551455
}
14561456
}
14571457
}
@@ -1469,8 +1469,7 @@ char **NpyArr_encodeLabels(PyArrayObject *labels, PyObjectEncoder *enc,
14691469
if (type_num == NPY_DATETIME) {
14701470
cLabel = int64ToIso(nanosecVal, base, &len);
14711471
} else {
1472-
cLabel = PyDateTimeToIso((PyDateTime_Date *)item,
1473-
base, &len);
1472+
cLabel = PyDateTimeToIso(item, base, &len);
14741473
}
14751474
}
14761475
if (cLabel == NULL) {
@@ -1683,7 +1682,7 @@ void Object_beginTypeContext(JSOBJ _obj, JSONTypeContext *tc) {
16831682
NPY_DATETIMEUNIT base =
16841683
((PyObjectEncoder *)tc->encoder)->datetimeUnit;
16851684
GET_TC(tc)->longValue =
1686-
PyDateTimeToEpoch((PyDateTime_Date *)obj, base);
1685+
PyDateTimeToEpoch(obj, base);
16871686
tc->type = JT_LONG;
16881687
}
16891688
return;
@@ -1710,7 +1709,7 @@ void Object_beginTypeContext(JSOBJ _obj, JSONTypeContext *tc) {
17101709
NPY_DATETIMEUNIT base =
17111710
((PyObjectEncoder *)tc->encoder)->datetimeUnit;
17121711
GET_TC(tc)->longValue =
1713-
PyDateTimeToEpoch((PyDateTime_Date *)obj, base);
1712+
PyDateTimeToEpoch(obj, base);
17141713
tc->type = JT_LONG;
17151714
}
17161715
return;

pandas/_libs/tslibs/src/datetime/np_datetime.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ This file is derived from NumPy 1.7. See NUMPY_LICENSE.txt
2121
#endif // NPY_NO_DEPRECATED_API
2222

2323
#include <Python.h>
24-
#include <datetime.h>
2524

2625
#include <numpy/arrayobject.h>
2726
#include <numpy/arrayscalars.h>
@@ -313,15 +312,14 @@ int cmp_npy_datetimestruct(const npy_datetimestruct *a,
313312
* object into a NumPy npy_datetimestruct. Uses tzinfo (if present)
314313
* to convert to UTC time.
315314
*
316-
* While the C API has PyDate_* and PyDateTime_* functions, the following
317-
* implementation just asks for attributes, and thus supports
318-
* datetime duck typing. The tzinfo time zone conversion would require
319-
* this style of access anyway.
315+
* The following implementation just asks for attributes, and thus
316+
* supports datetime duck typing. The tzinfo time zone conversion
317+
* requires this style of access as well.
320318
*
321319
* Returns -1 on error, 0 on success, and 1 (with no error set)
322320
* if obj doesn't have the needed date or datetime attributes.
323321
*/
324-
int convert_pydatetime_to_datetimestruct(PyDateTime_Date *dtobj,
322+
int convert_pydatetime_to_datetimestruct(PyObject *dtobj,
325323
npy_datetimestruct *out) {
326324
// Assumes that obj is a valid datetime object
327325
PyObject *tmp;

pandas/_libs/tslibs/src/datetime/np_datetime.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ This file is derived from NumPy 1.7. See NUMPY_LICENSE.txt
2222
#endif // NPY_NO_DEPRECATED_API
2323

2424
#include <numpy/ndarraytypes.h>
25-
#include <datetime.h>
2625

2726
typedef struct {
2827
npy_int64 days;
@@ -35,7 +34,7 @@ extern const npy_datetimestruct _NS_MAX_DTS;
3534
// stuff pandas needs
3635
// ----------------------------------------------------------------------------
3736

38-
int convert_pydatetime_to_datetimestruct(PyDateTime_Date *dtobj,
37+
int convert_pydatetime_to_datetimestruct(PyObject *dtobj,
3938
npy_datetimestruct *out);
4039

4140
npy_datetime npy_datetimestruct_to_datetime(NPY_DATETIMEUNIT base,

pandas/core/arrays/datetimelike.py

Lines changed: 27 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1129,56 +1129,46 @@ def _sub_period(self, other):
11291129
def _add_offset(self, offset):
11301130
raise AbstractMethodError(self)
11311131

1132-
def _add_delta(self, other):
1132+
def _add_timedeltalike_scalar(self, other):
11331133
"""
1134-
Add a timedelta-like, Tick or TimedeltaIndex-like object
1135-
to self, yielding an int64 numpy array
1136-
1137-
Parameters
1138-
----------
1139-
delta : {timedelta, np.timedelta64, Tick,
1140-
TimedeltaIndex, ndarray[timedelta64]}
1134+
Add a delta of a timedeltalike
11411135
11421136
Returns
11431137
-------
1144-
result : ndarray[int64]
1145-
1146-
Notes
1147-
-----
1148-
The result's name is set outside of _add_delta by the calling
1149-
method (__add__ or __sub__), if necessary (i.e. for Indexes).
1150-
"""
1151-
if isinstance(other, (Tick, timedelta, np.timedelta64)):
1152-
new_values = self._add_timedeltalike_scalar(other)
1153-
elif is_timedelta64_dtype(other):
1154-
# ndarray[timedelta64] or TimedeltaArray/index
1155-
new_values = self._add_delta_tdi(other)
1156-
1157-
return new_values
1158-
1159-
def _add_timedeltalike_scalar(self, other):
1160-
"""
1161-
Add a delta of a timedeltalike
1162-
return the i8 result view
1138+
Same type as self
11631139
"""
11641140
if isna(other):
11651141
# i.e np.timedelta64("NaT"), not recognized by delta_to_nanoseconds
11661142
new_values = np.empty(self.shape, dtype="i8")
11671143
new_values[:] = iNaT
1168-
return new_values
1144+
return type(self)(new_values, dtype=self.dtype)
11691145

11701146
inc = delta_to_nanoseconds(other)
11711147
new_values = checked_add_with_arr(self.asi8, inc, arr_mask=self._isnan).view(
11721148
"i8"
11731149
)
11741150
new_values = self._maybe_mask_results(new_values)
1175-
return new_values.view("i8")
11761151

1177-
def _add_delta_tdi(self, other):
1152+
new_freq = None
1153+
if isinstance(self.freq, Tick) or is_period_dtype(self.dtype):
1154+
# adding a scalar preserves freq
1155+
new_freq = self.freq
1156+
1157+
if new_freq is not None:
1158+
# fastpath that doesnt require inference
1159+
return type(self)(new_values, dtype=self.dtype, freq=new_freq)
1160+
return type(self)._from_sequence(new_values, dtype=self.dtype, freq="infer")
1161+
1162+
def _add_timedelta_arraylike(self, other):
11781163
"""
11791164
Add a delta of a TimedeltaIndex
1180-
return the i8 result view
1165+
1166+
Returns
1167+
-------
1168+
Same type as self
11811169
"""
1170+
# overriden by PeriodArray
1171+
11821172
if len(self) != len(other):
11831173
raise ValueError("cannot add indices of unequal length")
11841174

@@ -1196,7 +1186,8 @@ def _add_delta_tdi(self, other):
11961186
if self._hasnans or other._hasnans:
11971187
mask = (self._isnan) | (other._isnan)
11981188
new_values[mask] = iNaT
1199-
return new_values.view("i8")
1189+
1190+
return type(self)._from_sequence(new_values, dtype=self.dtype, freq="infer")
12001191

12011192
def _add_nat(self):
12021193
"""
@@ -1338,7 +1329,7 @@ def __add__(self, other):
13381329
if other is NaT:
13391330
result = self._add_nat()
13401331
elif isinstance(other, (Tick, timedelta, np.timedelta64)):
1341-
result = self._add_delta(other)
1332+
result = self._add_timedeltalike_scalar(other)
13421333
elif isinstance(other, DateOffset):
13431334
# specifically _not_ a Tick
13441335
result = self._add_offset(other)
@@ -1354,7 +1345,7 @@ def __add__(self, other):
13541345
# array-like others
13551346
elif is_timedelta64_dtype(other):
13561347
# TimedeltaIndex, ndarray[timedelta64]
1357-
result = self._add_delta(other)
1348+
result = self._add_timedelta_arraylike(other)
13581349
elif is_object_dtype(other):
13591350
# e.g. Array/Index of DateOffset objects
13601351
result = self._addsub_object_array(other, operator.add)
@@ -1390,7 +1381,7 @@ def __sub__(self, other):
13901381
if other is NaT:
13911382
result = self._sub_nat()
13921383
elif isinstance(other, (Tick, timedelta, np.timedelta64)):
1393-
result = self._add_delta(-other)
1384+
result = self._add_timedeltalike_scalar(-other)
13941385
elif isinstance(other, DateOffset):
13951386
# specifically _not_ a Tick
13961387
result = self._add_offset(-other)
@@ -1409,7 +1400,7 @@ def __sub__(self, other):
14091400
# array-like others
14101401
elif is_timedelta64_dtype(other):
14111402
# TimedeltaIndex, ndarray[timedelta64]
1412-
result = self._add_delta(-other)
1403+
result = self._add_timedelta_arraylike(-other)
14131404
elif is_object_dtype(other):
14141405
# e.g. Array/Index of DateOffset objects
14151406
result = self._addsub_object_array(other, operator.sub)

pandas/core/arrays/datetimes.py

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -718,23 +718,6 @@ def _sub_datetimelike_scalar(self, other):
718718
result = self._maybe_mask_results(result)
719719
return result.view("timedelta64[ns]")
720720

721-
def _add_delta(self, delta):
722-
"""
723-
Add a timedelta-like, Tick, or TimedeltaIndex-like object
724-
to self, yielding a new DatetimeArray
725-
726-
Parameters
727-
----------
728-
other : {timedelta, np.timedelta64, Tick,
729-
TimedeltaIndex, ndarray[timedelta64]}
730-
731-
Returns
732-
-------
733-
result : DatetimeArray
734-
"""
735-
new_values = super()._add_delta(delta)
736-
return type(self)._from_sequence(new_values, tz=self.tz, freq="infer")
737-
738721
# -----------------------------------------------------------------
739722
# Timezone Conversion and Localization Methods
740723

0 commit comments

Comments
 (0)