Skip to content

Commit 0182e3f

Browse files
authored
Merge pull request #9 from pandas-dev/master
BUG: -1 to the power of pd.NA was returning -1 (pandas-dev#30960)
2 parents b5182ab + 67fcdef commit 0182e3f

File tree

8 files changed

+42
-32
lines changed

8 files changed

+42
-32
lines changed

doc/source/user_guide/missing_data.rst

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -831,7 +831,6 @@ Operation Result
831831
================ ======
832832
``pd.NA ** 0`` 0
833833
``1 ** pd.NA`` 1
834-
``-1 ** pd.NA`` -1
835834
================ ======
836835

837836
In equality and comparison operations, ``pd.NA`` also propagates. This deviates

pandas/_libs/missing.pyx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -417,12 +417,12 @@ class NAType(C_NAType):
417417
if other is C_NA:
418418
return NA
419419
elif isinstance(other, (numbers.Number, np.bool_)):
420-
if other == 1 or other == -1:
420+
if other == 1:
421421
return other
422422
else:
423423
return NA
424424
elif isinstance(other, np.ndarray):
425-
return np.where((other == 1) | (other == -1), other, NA)
425+
return np.where(other == 1, other, NA)
426426

427427
return NotImplemented
428428

pandas/core/frame.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,6 @@
102102
from pandas.core.arrays.datetimelike import DatetimeLikeArrayMixin as DatetimeLikeArray
103103
from pandas.core.arrays.sparse import SparseFrameAccessor
104104
from pandas.core.generic import NDFrame, _shared_docs
105-
from pandas.core.groupby import generic as groupby_generic
106105
from pandas.core.indexes import base as ibase
107106
from pandas.core.indexes.api import Index, ensure_index, ensure_index_from_sequences
108107
from pandas.core.indexes.datetimes import DatetimeIndex
@@ -129,6 +128,7 @@
129128
import pandas.plotting
130129

131130
if TYPE_CHECKING:
131+
from pandas.core.groupby.generic import DataFrameGroupBy
132132
from pandas.io.formats.style import Styler
133133

134134
# ---------------------------------------------------------------------
@@ -5777,13 +5777,14 @@ def groupby(
57775777
group_keys: bool = True,
57785778
squeeze: bool = False,
57795779
observed: bool = False,
5780-
) -> "groupby_generic.DataFrameGroupBy":
5780+
) -> "DataFrameGroupBy":
5781+
from pandas.core.groupby.generic import DataFrameGroupBy
57815782

57825783
if level is None and by is None:
57835784
raise TypeError("You have to supply one of 'by' and 'level'")
57845785
axis = self._get_axis_number(axis)
57855786

5786-
return groupby_generic.DataFrameGroupBy(
5787+
return DataFrameGroupBy(
57875788
obj=self,
57885789
keys=by,
57895790
axis=axis,

pandas/core/generic.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import re
99
from textwrap import dedent
1010
from typing import (
11+
TYPE_CHECKING,
1112
Any,
1213
Callable,
1314
Dict,
@@ -101,6 +102,9 @@
101102
from pandas.io.formats.printing import pprint_thing
102103
from pandas.tseries.frequencies import to_offset
103104

105+
if TYPE_CHECKING:
106+
from pandas.core.resample import Resampler
107+
104108
# goal is to be able to define the docs close to function, while still being
105109
# able to share
106110
_shared_docs: Dict[str, str] = dict()
@@ -7685,7 +7689,7 @@ def resample(
76857689
base: int = 0,
76867690
on=None,
76877691
level=None,
7688-
):
7692+
) -> "Resampler":
76897693
"""
76907694
Resample time-series data.
76917695
@@ -7950,10 +7954,10 @@ def resample(
79507954
2000-01-04 36 90
79517955
"""
79527956

7953-
from pandas.core.resample import resample
7957+
from pandas.core.resample import get_resampler
79547958

79557959
axis = self._get_axis_number(axis)
7956-
return resample(
7960+
return get_resampler(
79577961
self,
79587962
freq=rule,
79597963
label=label,

pandas/core/resample.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1262,15 +1262,15 @@ def _constructor(self):
12621262
return TimedeltaIndexResampler
12631263

12641264

1265-
def resample(obj, kind=None, **kwds):
1265+
def get_resampler(obj, kind=None, **kwds):
12661266
"""
12671267
Create a TimeGrouper and return our resampler.
12681268
"""
12691269
tg = TimeGrouper(**kwds)
12701270
return tg._get_resampler(obj, kind=kind)
12711271

12721272

1273-
resample.__doc__ = Resampler.__doc__
1273+
get_resampler.__doc__ = Resampler.__doc__
12741274

12751275

12761276
def get_resampler_for_grouping(

pandas/core/series.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@
7070
is_empty_data,
7171
sanitize_array,
7272
)
73-
from pandas.core.groupby import generic as groupby_generic
7473
from pandas.core.indexers import maybe_convert_indices
7574
from pandas.core.indexes.accessors import CombinedDatetimelikeProperties
7675
from pandas.core.indexes.api import (
@@ -94,6 +93,7 @@
9493

9594
if TYPE_CHECKING:
9695
from pandas.core.frame import DataFrame
96+
from pandas.core.groupby.generic import SeriesGroupBy
9797

9898
__all__ = ["Series"]
9999

@@ -1634,13 +1634,14 @@ def groupby(
16341634
group_keys: bool = True,
16351635
squeeze: bool = False,
16361636
observed: bool = False,
1637-
) -> "groupby_generic.SeriesGroupBy":
1637+
) -> "SeriesGroupBy":
1638+
from pandas.core.groupby.generic import SeriesGroupBy
16381639

16391640
if level is None and by is None:
16401641
raise TypeError("You have to supply one of 'by' and 'level'")
16411642
axis = self._get_axis_number(axis)
16421643

1643-
return groupby_generic.SeriesGroupBy(
1644+
return SeriesGroupBy(
16441645
obj=self,
16451646
keys=by,
16461647
axis=axis,

pandas/tests/arrays/test_integer.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -363,24 +363,26 @@ def test_divide_by_zero(self, zero, negative):
363363
tm.assert_numpy_array_equal(result, expected)
364364

365365
def test_pow_scalar(self):
366-
a = pd.array([0, 1, None, 2], dtype="Int64")
366+
a = pd.array([-1, 0, 1, None, 2], dtype="Int64")
367367
result = a ** 0
368-
expected = pd.array([1, 1, 1, 1], dtype="Int64")
368+
expected = pd.array([1, 1, 1, 1, 1], dtype="Int64")
369369
tm.assert_extension_array_equal(result, expected)
370370

371371
result = a ** 1
372-
expected = pd.array([0, 1, None, 2], dtype="Int64")
372+
expected = pd.array([-1, 0, 1, None, 2], dtype="Int64")
373373
tm.assert_extension_array_equal(result, expected)
374374

375375
result = a ** pd.NA
376-
expected = pd.array([None, 1, None, None], dtype="Int64")
376+
expected = pd.array([None, None, 1, None, None], dtype="Int64")
377377
tm.assert_extension_array_equal(result, expected)
378378

379379
result = a ** np.nan
380-
expected = np.array([np.nan, 1, np.nan, np.nan], dtype="float64")
380+
expected = np.array([np.nan, np.nan, 1, np.nan, np.nan], dtype="float64")
381381
tm.assert_numpy_array_equal(result, expected)
382382

383383
# reversed
384+
a = a[1:] # Can't raise integers to negative powers.
385+
384386
result = 0 ** a
385387
expected = pd.array([1, 0, None, 0], dtype="Int64")
386388
tm.assert_extension_array_equal(result, expected)

pandas/tests/scalar/test_na_scalar.py

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -96,19 +96,7 @@ def test_pow_special(value, asarray):
9696

9797

9898
@pytest.mark.parametrize(
99-
"value",
100-
[
101-
1,
102-
1.0,
103-
-1,
104-
-1.0,
105-
True,
106-
np.bool_(True),
107-
np.int_(1),
108-
np.float_(1),
109-
np.int_(-1),
110-
np.float_(-1),
111-
],
99+
"value", [1, 1.0, True, np.bool_(True), np.int_(1), np.float_(1)],
112100
)
113101
@pytest.mark.parametrize("asarray", [True, False])
114102
def test_rpow_special(value, asarray):
@@ -125,6 +113,21 @@ def test_rpow_special(value, asarray):
125113
assert result == value
126114

127115

116+
@pytest.mark.parametrize(
117+
"value", [-1, -1.0, np.int_(-1), np.float_(-1)],
118+
)
119+
@pytest.mark.parametrize("asarray", [True, False])
120+
def test_rpow_minus_one(value, asarray):
121+
if asarray:
122+
value = np.array([value])
123+
result = value ** pd.NA
124+
125+
if asarray:
126+
result = result[0]
127+
128+
assert pd.isna(result)
129+
130+
128131
def test_unary_ops():
129132
assert +NA is NA
130133
assert -NA is NA

0 commit comments

Comments
 (0)