Skip to content

Commit 4a72863

Browse files
committed
Merge branch 'master' of https://github.com/pandas-dev/pandas into cln-arith
2 parents f91c56b + 6ec0f62 commit 4a72863

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+339
-256
lines changed

.github/CODE_OF_CONDUCT.md

-1
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,3 @@ and the [Swift Code of Conduct][swift].
6060
[homepage]: https://www.contributor-covenant.org
6161
[version]: https://www.contributor-covenant.org/version/1/3/0/
6262
[swift]: https://swift.org/community/#code-of-conduct
63-

.pre-commit-config.yaml

+5
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,8 @@ repos:
4747
rev: v1.2.2
4848
hooks:
4949
- id: yesqa
50+
- repo: https://github.com/pre-commit/pre-commit-hooks
51+
rev: v3.2.0
52+
hooks:
53+
- id: end-of-file-fixer
54+
exclude: '.html$|^LICENSES/|.csv$|.txt$|.svg$|.py$'

AUTHORS.md

-1
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,3 @@ pandas is distributed under a 3-clause ("Simplified" or "New") BSD
5454
license. Parts of NumPy, SciPy, numpydoc, bottleneck, which all have
5555
BSD-compatible licenses, are included. Their licenses follow the pandas
5656
license.
57-

ci/travis_process_gbq_encryption.sh

-1
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,3 @@ elif [[ -n ${!TRAVIS_IV_ENV} ]]; then
1010
export GBQ_PROJECT_ID='pandas-gbq-tests';
1111
echo 'Successfully decrypted gbq credentials'
1212
fi
13-

doc/data/iris.data

+1-1
Original file line numberDiff line numberDiff line change
@@ -148,4 +148,4 @@ SepalLength,SepalWidth,PetalLength,PetalWidth,Name
148148
6.3,2.5,5.0,1.9,Iris-virginica
149149
6.5,3.0,5.2,2.0,Iris-virginica
150150
6.2,3.4,5.4,2.3,Iris-virginica
151-
5.9,3.0,5.1,1.8,Iris-virginica
151+
5.9,3.0,5.1,1.8,Iris-virginica

doc/source/development/contributing.rst

+3
Original file line numberDiff line numberDiff line change
@@ -837,6 +837,9 @@ to run its checks by running::
837837

838838
without having to have done ``pre-commit install`` beforehand.
839839

840+
Note that if you have conflicting installations of ``virtualenv``, then you may get an
841+
error - see `here <https://github.com/pypa/virtualenv/issues/1875>`_.
842+
840843
Backwards compatibility
841844
~~~~~~~~~~~~~~~~~~~~~~~
842845

doc/source/development/developer.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -184,4 +184,4 @@ As an example of fully-formed metadata:
184184
'creator': {
185185
'library': 'pyarrow',
186186
'version': '0.13.0'
187-
}}
187+
}}

doc/source/getting_started/intro_tutorials/index.rst

-1
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,3 @@ Getting started tutorials
1919
08_combine_dataframes
2020
09_timeseries
2121
10_text_data
22-

doc/source/getting_started/overview.rst

-1
Original file line numberDiff line numberDiff line change
@@ -174,4 +174,3 @@ License
174174
-------
175175

176176
.. literalinclude:: ../../../LICENSE
177-

doc/source/reference/general_utility_functions.rst

-1
Original file line numberDiff line numberDiff line change
@@ -122,4 +122,3 @@ Bug report function
122122
:toctree: api/
123123

124124
show_versions
125-

doc/source/whatsnew/v0.14.0.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -1084,4 +1084,4 @@ Bug fixes
10841084
Contributors
10851085
~~~~~~~~~~~~
10861086

1087-
.. contributors:: v0.13.1..v0.14.0
1087+
.. contributors:: v0.13.1..v0.14.0

doc/source/whatsnew/v1.2.0.rst

+2-1
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,7 @@ Numeric
336336
- Bug in :class:`Series` where two :class:`Series` each have a :class:`DatetimeIndex` with different timezones having those indexes incorrectly changed when performing arithmetic operations (:issue:`33671`)
337337
- Bug in :meth:`pd._testing.assert_almost_equal` was incorrect for complex numeric types (:issue:`28235`)
338338
- Bug in :meth:`DataFrame.__rmatmul__` error handling reporting transposed shapes (:issue:`21581`)
339+
- Bug in :class:`IntegerArray` multiplication with ``timedelta`` and ``np.timedelta64`` objects (:issue:`36870`)
339340
- Bug in :class:`IntervalArray` comparisons with :class:`Series` not returning :class:`Series` (:issue:`36908`)
340341

341342
Conversion
@@ -424,6 +425,7 @@ Reshaping
424425
- Bug in :func:`union_indexes` where input index names are not preserved in some cases. Affects :func:`concat` and :class:`DataFrame` constructor (:issue:`13475`)
425426
- Bug in func :meth:`crosstab` when using multiple columns with ``margins=True`` and ``normalize=True`` (:issue:`35144`)
426427
- Bug in :meth:`DataFrame.agg` with ``func={'name':<FUNC>}`` incorrectly raising ``TypeError`` when ``DataFrame.columns==['Name']`` (:issue:`36212`)
428+
- Bug in :meth:`Series.transform` would give incorrect results or raise when the argument ``func`` was dictionary (:issue:`35811`)
427429
-
428430

429431
Sparse
@@ -446,7 +448,6 @@ Other
446448
- Bug in :meth:`DataFrame.replace` and :meth:`Series.replace` incorrectly raising ``AssertionError`` instead of ``ValueError`` when invalid parameter combinations are passed (:issue:`36045`)
447449
- Bug in :meth:`DataFrame.replace` and :meth:`Series.replace` with numeric values and string ``to_replace`` (:issue:`34789`)
448450
- Fixed metadata propagation in the :class:`Series.dt` accessor (:issue:`28283`)
449-
- Bug in :meth:`Series.transform` would give incorrect results or raise when the argument ``func`` was dictionary (:issue:`35811`)
450451
- Bug in :meth:`Index.union` behaving differently depending on whether operand is a :class:`Index` or other list-like (:issue:`36384`)
451452

452453
.. ---------------------------------------------------------------------------

flake8/cython-template.cfg

-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
[flake8]
22
filename = *.pxi.in
33
select = E501,E302,E203,E111,E114,E221,E303,E231,E126,F403
4-

pandas/_libs/src/klib/khash_python.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -121,4 +121,4 @@ void PANDAS_INLINE kh_destroy_str_starts(kh_str_starts_t* table) {
121121

122122
void PANDAS_INLINE kh_resize_str_starts(kh_str_starts_t* table, khint_t val) {
123123
kh_resize_str(table->table, val);
124-
}
124+
}

pandas/_libs/testing.pyx

+2-25
Original file line numberDiff line numberDiff line change
@@ -7,36 +7,13 @@ from numpy cimport import_array
77

88
import_array()
99

10-
from pandas._libs.util cimport is_array
1110
from pandas._libs.lib import is_complex
11+
from pandas._libs.util cimport is_array, is_real_number_object
1212

1313
from pandas.core.dtypes.common import is_dtype_equal
1414
from pandas.core.dtypes.missing import array_equivalent, isna
1515

1616

17-
cdef NUMERIC_TYPES = (
18-
bool,
19-
int,
20-
float,
21-
np.bool_,
22-
np.int8,
23-
np.int16,
24-
np.int32,
25-
np.int64,
26-
np.uint8,
27-
np.uint16,
28-
np.uint32,
29-
np.uint64,
30-
np.float16,
31-
np.float32,
32-
np.float64,
33-
)
34-
35-
36-
cdef bint is_comparable_as_number(obj):
37-
return isinstance(obj, NUMERIC_TYPES)
38-
39-
4017
cdef bint isiterable(obj):
4118
return hasattr(obj, '__iter__')
4219

@@ -200,7 +177,7 @@ cpdef assert_almost_equal(a, b,
200177
# object comparison
201178
return True
202179

203-
if is_comparable_as_number(a) and is_comparable_as_number(b):
180+
if is_real_number_object(a) and is_real_number_object(b):
204181
if array_equivalent(a, b, strict_nan=True):
205182
# inf comparison
206183
return True

pandas/_libs/tslibs/util.pxd

+4
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,10 @@ cdef inline bint is_bool_object(object obj) nogil:
121121
PyObject_TypeCheck(obj, &PyBoolArrType_Type))
122122

123123

124+
cdef inline bint is_real_number_object(object obj) nogil:
125+
return is_bool_object(obj) or is_integer_object(obj) or is_float_object(obj)
126+
127+
124128
cdef inline bint is_timedelta64_object(object obj) nogil:
125129
"""
126130
Cython equivalent of `isinstance(val, np.timedelta64)`

pandas/_libs/util.pxd

-1
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,3 @@ cdef inline void set_array_not_contiguous(ndarray ao) nogil:
4848
# ao->flags &= ~(NPY_ARRAY_C_CONTIGUOUS | NPY_ARRAY_F_CONTIGUOUS);
4949
PyArray_CLEARFLAGS(ao,
5050
(NPY_ARRAY_C_CONTIGUOUS | NPY_ARRAY_F_CONTIGUOUS))
51-

pandas/core/aggregation.py

+38-11
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,17 @@
1717
Sequence,
1818
Tuple,
1919
Union,
20+
cast,
2021
)
2122

22-
from pandas._typing import AggFuncType, Axis, FrameOrSeries, Label
23+
from pandas._typing import (
24+
AggFuncType,
25+
AggFuncTypeBase,
26+
Axis,
27+
FrameOrSeries,
28+
FrameOrSeriesUnion,
29+
Label,
30+
)
2331

2432
from pandas.core.dtypes.common import is_dict_like, is_list_like
2533
from pandas.core.dtypes.generic import ABCDataFrame, ABCSeries
@@ -391,7 +399,7 @@ def validate_func_kwargs(
391399

392400
def transform(
393401
obj: FrameOrSeries, func: AggFuncType, axis: Axis, *args, **kwargs
394-
) -> FrameOrSeries:
402+
) -> FrameOrSeriesUnion:
395403
"""
396404
Transform a DataFrame or Series
397405
@@ -424,16 +432,20 @@ def transform(
424432
assert not is_series
425433
return transform(obj.T, func, 0, *args, **kwargs).T
426434

427-
if isinstance(func, list):
435+
if is_list_like(func) and not is_dict_like(func):
436+
func = cast(List[AggFuncTypeBase], func)
437+
# Convert func equivalent dict
428438
if is_series:
429439
func = {com.get_callable_name(v) or v: v for v in func}
430440
else:
431441
func = {col: func for col in obj}
432442

433-
if isinstance(func, dict):
443+
if is_dict_like(func):
444+
func = cast(Dict[Label, Union[AggFuncTypeBase, List[AggFuncTypeBase]]], func)
434445
return transform_dict_like(obj, func, *args, **kwargs)
435446

436447
# func is either str or callable
448+
func = cast(AggFuncTypeBase, func)
437449
try:
438450
result = transform_str_or_callable(obj, func, *args, **kwargs)
439451
except Exception:
@@ -451,37 +463,52 @@ def transform(
451463
return result
452464

453465

454-
def transform_dict_like(obj, func, *args, **kwargs):
466+
def transform_dict_like(
467+
obj: FrameOrSeries,
468+
func: Dict[Label, Union[AggFuncTypeBase, List[AggFuncTypeBase]]],
469+
*args,
470+
**kwargs,
471+
):
455472
"""
456473
Compute transform in the case of a dict-like func
457474
"""
458475
from pandas.core.reshape.concat import concat
459476

477+
if len(func) == 0:
478+
raise ValueError("No transform functions were provided")
479+
460480
if obj.ndim != 1:
481+
# Check for missing columns on a frame
461482
cols = sorted(set(func.keys()) - set(obj.columns))
462483
if len(cols) > 0:
463484
raise SpecificationError(f"Column(s) {cols} do not exist")
464485

465-
if any(isinstance(v, dict) for v in func.values()):
486+
# Can't use func.values(); wouldn't work for a Series
487+
if any(is_dict_like(v) for _, v in func.items()):
466488
# GH 15931 - deprecation of renaming keys
467489
raise SpecificationError("nested renamer is not supported")
468490

469-
results = {}
491+
results: Dict[Label, FrameOrSeriesUnion] = {}
470492
for name, how in func.items():
471493
colg = obj._gotitem(name, ndim=1)
472494
try:
473495
results[name] = transform(colg, how, 0, *args, **kwargs)
474-
except Exception as e:
475-
if str(e) == "Function did not transform":
476-
raise e
496+
except Exception as err:
497+
if (
498+
str(err) == "Function did not transform"
499+
or str(err) == "No transform functions were provided"
500+
):
501+
raise err
477502

478503
# combine results
479504
if len(results) == 0:
480505
raise ValueError("Transform function failed")
481506
return concat(results, axis=1)
482507

483508

484-
def transform_str_or_callable(obj, func, *args, **kwargs):
509+
def transform_str_or_callable(
510+
obj: FrameOrSeries, func: AggFuncTypeBase, *args, **kwargs
511+
) -> FrameOrSeriesUnion:
485512
"""
486513
Compute transform in the case of a string or callable func
487514
"""

pandas/core/arrays/_mixins.py

+9
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
from pandas.util._decorators import cache_readonly, doc
99
from pandas.util._validators import validate_fillna_kwargs
1010

11+
from pandas.core.dtypes.common import is_dtype_equal
1112
from pandas.core.dtypes.inference import is_array_like
13+
from pandas.core.dtypes.missing import array_equivalent
1214

1315
from pandas.core import missing
1416
from pandas.core.algorithms import take, unique
@@ -115,6 +117,13 @@ def T(self: _T) -> _T:
115117

116118
# ------------------------------------------------------------------------
117119

120+
def equals(self, other) -> bool:
121+
if type(self) is not type(other):
122+
return False
123+
if not is_dtype_equal(self.dtype, other.dtype):
124+
return False
125+
return bool(array_equivalent(self._ndarray, other._ndarray))
126+
118127
def _values_for_argsort(self):
119128
return self._ndarray
120129

pandas/core/arrays/integer.py

+11-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1+
from datetime import timedelta
12
import numbers
23
from typing import TYPE_CHECKING, Dict, List, Optional, Tuple, Type, Union
34
import warnings
45

56
import numpy as np
67

7-
from pandas._libs import lib, missing as libmissing
8+
from pandas._libs import Timedelta, iNaT, lib, missing as libmissing
89
from pandas._typing import ArrayLike, DtypeObj
910
from pandas.compat import set_function_name
1011
from pandas.compat.numpy import function as nv
@@ -581,6 +582,12 @@ def _maybe_mask_result(self, result, mask, other, op_name: str):
581582
result[mask] = np.nan
582583
return result
583584

585+
if result.dtype == "timedelta64[ns]":
586+
from pandas.core.arrays import TimedeltaArray
587+
588+
result[mask] = iNaT
589+
return TimedeltaArray._simple_new(result)
590+
584591
return type(self)(result, mask, copy=False)
585592

586593
@classmethod
@@ -609,6 +616,9 @@ def integer_arithmetic_method(self, other):
609616
if not (is_float_dtype(other) or is_integer_dtype(other)):
610617
raise TypeError("can only perform ops with numeric values")
611618

619+
elif isinstance(other, (timedelta, np.timedelta64)):
620+
other = Timedelta(other)
621+
612622
else:
613623
if not (is_float(other) or is_integer(other) or other is libmissing.NA):
614624
raise TypeError("can only perform ops with numeric values")

pandas/core/arrays/interval.py

+10
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,16 @@ def astype(self, dtype, copy=True):
708708
msg = f"Cannot cast {type(self).__name__} to dtype {dtype}"
709709
raise TypeError(msg) from err
710710

711+
def equals(self, other) -> bool:
712+
if type(self) != type(other):
713+
return False
714+
715+
return bool(
716+
self.closed == other.closed
717+
and self.left.equals(other.left)
718+
and self.right.equals(other.right)
719+
)
720+
711721
@classmethod
712722
def _concat_same_type(cls, to_concat):
713723
"""

0 commit comments

Comments
 (0)