Skip to content

Commit 00c0f12

Browse files
authored
Merge branch 'main' into cow_putmask
2 parents bdde4df + fdd7163 commit 00c0f12

File tree

18 files changed

+116
-145
lines changed

18 files changed

+116
-145
lines changed

.github/workflows/python-dev.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ jobs:
7373
run: |
7474
python --version
7575
python -m pip install --upgrade pip setuptools wheel
76-
python -m pip install -i https://pypi.anaconda.org/scipy-wheels-nightly/simple numpy
76+
python -m pip install --extra-index-url https://pypi.anaconda.org/scipy-wheels-nightly/simple numpy
7777
python -m pip install git+https://github.com/nedbat/coveragepy.git
7878
python -m pip install versioneer[toml]
7979
python -m pip install python-dateutil pytz cython hypothesis==6.52.1 pytest>=6.2.5 pytest-xdist pytest-cov pytest-asyncio>=0.17

doc/scripts/eval_performance.py

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from pandas import DataFrame
77

88
setup_common = """from pandas import DataFrame
9+
import numpy as np
910
df = DataFrame(np.random.randn(%d, 3), columns=list('abc'))
1011
%s"""
1112

doc/source/whatsnew/v1.5.3.rst

+7
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@ Bug fixes
3838

3939
Other
4040
~~~~~
41+
42+
.. note::
43+
44+
If you are using :meth:`DataFrame.to_sql`, :func:`read_sql`, :func:`read_sql_table`, or :func:`read_sql_query` with SQLAlchemy 1.4.46 or greater,
45+
you may see a ``sqlalchemy.exc.RemovedIn20Warning``. These warnings can be safely ignored for the SQLAlchemy 1.4.x releases
46+
as pandas works toward compatibility with SQLAlchemy 2.0.
47+
4148
- Reverted deprecation (:issue:`45324`) of behavior of :meth:`Series.__getitem__` and :meth:`Series.__setitem__` slicing with an integer :class:`Index`; this will remain positional (:issue:`49612`)
4249
-
4350

doc/source/whatsnew/v2.0.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,7 @@ Other API changes
515515
- Default value of ``dtype`` in :func:`get_dummies` is changed to ``bool`` from ``uint8`` (:issue:`45848`)
516516
- :meth:`DataFrame.astype`, :meth:`Series.astype`, and :meth:`DatetimeIndex.astype` casting datetime64 data to any of "datetime64[s]", "datetime64[ms]", "datetime64[us]" will return an object with the given resolution instead of coercing back to "datetime64[ns]" (:issue:`48928`)
517517
- :meth:`DataFrame.astype`, :meth:`Series.astype`, and :meth:`DatetimeIndex.astype` casting timedelta64 data to any of "timedelta64[s]", "timedelta64[ms]", "timedelta64[us]" will return an object with the given resolution instead of coercing to "float64" dtype (:issue:`48963`)
518+
- :meth:`DatetimeIndex.astype`, :meth:`TimedeltaIndex.astype`, :meth:`PeriodIndex.astype` :meth:`Series.astype`, :meth:`DataFrame.astype` with ``datetime64``, ``timedelta64`` or :class:`PeriodDtype` dtypes no longer allow converting to integer dtypes other than "int64", do ``obj.astype('int64', copy=False).astype(dtype)`` instead (:issue:`49715`)
518519
- :meth:`Index.astype` now allows casting from ``float64`` dtype to datetime-like dtypes, matching :class:`Series` behavior (:issue:`49660`)
519520
- Passing data with dtype of "timedelta64[s]", "timedelta64[ms]", or "timedelta64[us]" to :class:`TimedeltaIndex`, :class:`Series`, or :class:`DataFrame` constructors will now retain that dtype instead of casting to "timedelta64[ns]"; timedelta64 data with lower resolution will be cast to the lowest supported resolution "timedelta64[s]" (:issue:`49014`)
520521
- Passing ``dtype`` of "timedelta64[s]", "timedelta64[ms]", or "timedelta64[us]" to :class:`TimedeltaIndex`, :class:`Series`, or :class:`DataFrame` constructors will now retain that dtype instead of casting to "timedelta64[ns]"; passing a dtype with lower resolution for :class:`Series` or :class:`DataFrame` will be cast to the lowest supported resolution "timedelta64[s]" (:issue:`49014`)

pandas/core/arrays/datetimelike.py

+4-34
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,6 @@
9696
is_period_dtype,
9797
is_string_dtype,
9898
is_timedelta64_dtype,
99-
is_unsigned_integer_dtype,
10099
pandas_dtype,
101100
)
102101
from pandas.core.dtypes.dtypes import (
@@ -468,39 +467,10 @@ def astype(self, dtype, copy: bool = True):
468467
# we deliberately ignore int32 vs. int64 here.
469468
# See https://github.com/pandas-dev/pandas/issues/24381 for more.
470469
values = self.asi8
471-
472-
if is_unsigned_integer_dtype(dtype):
473-
# Again, we ignore int32 vs. int64
474-
values = values.view("uint64")
475-
if dtype != np.uint64:
476-
# GH#45034
477-
warnings.warn(
478-
f"The behavior of .astype from {self.dtype} to {dtype} is "
479-
"deprecated. In a future version, this astype will return "
480-
"exactly the specified dtype instead of uint64, and will "
481-
"raise if that conversion overflows.",
482-
FutureWarning,
483-
stacklevel=find_stack_level(),
484-
)
485-
elif (self.asi8 < 0).any():
486-
# GH#45034
487-
warnings.warn(
488-
f"The behavior of .astype from {self.dtype} to {dtype} is "
489-
"deprecated. In a future version, this astype will "
490-
"raise if the conversion overflows, as it did in this "
491-
"case with negative int64 values.",
492-
FutureWarning,
493-
stacklevel=find_stack_level(),
494-
)
495-
elif dtype != np.int64:
496-
# GH#45034
497-
warnings.warn(
498-
f"The behavior of .astype from {self.dtype} to {dtype} is "
499-
"deprecated. In a future version, this astype will return "
500-
"exactly the specified dtype instead of int64, and will "
501-
"raise if that conversion overflows.",
502-
FutureWarning,
503-
stacklevel=find_stack_level(),
470+
if dtype != np.int64:
471+
raise TypeError(
472+
f"Converting from {self.dtype} to {dtype} is not supported. "
473+
"Do obj.astype('int64').astype(dtype) instead"
504474
)
505475

506476
if copy:

pandas/core/dtypes/astype.py

-10
Original file line numberDiff line numberDiff line change
@@ -171,16 +171,6 @@ def astype_array(values: ArrayLike, dtype: DtypeObj, copy: bool = False) -> Arra
171171
-------
172172
ndarray or ExtensionArray
173173
"""
174-
if (
175-
values.dtype.kind in ["m", "M"]
176-
and dtype.kind in ["i", "u"]
177-
and isinstance(dtype, np.dtype)
178-
and dtype.itemsize != 8
179-
):
180-
# TODO(2.0) remove special case once deprecation on DTA/TDA is enforced
181-
msg = rf"cannot astype a datetimelike from [{values.dtype}] to [{dtype}]"
182-
raise TypeError(msg)
183-
184174
if is_dtype_equal(values.dtype, dtype):
185175
if copy:
186176
return values.copy()

pandas/core/dtypes/common.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -638,7 +638,11 @@ def is_any_int_dtype(arr_or_dtype) -> bool:
638638
>>> is_any_int_dtype(pd.Index([1, 2.])) # float
639639
False
640640
"""
641-
return _is_dtype_type(arr_or_dtype, classes(np.integer, np.timedelta64))
641+
return _is_dtype_type(
642+
arr_or_dtype, classes(np.integer, np.timedelta64)
643+
) or _is_dtype(
644+
arr_or_dtype, lambda typ: isinstance(typ, ExtensionDtype) and typ.kind in "iu"
645+
)
642646

643647

644648
def is_integer_dtype(arr_or_dtype) -> bool:

pandas/tests/arrays/period/test_astype.py

+7-20
Original file line numberDiff line numberDiff line change
@@ -14,26 +14,13 @@ def test_astype_int(dtype):
1414
# Period/Datetime/Timedelta astype
1515
arr = period_array(["2000", "2001", None], freq="D")
1616

17-
if np.dtype(dtype).kind == "u":
18-
expected_dtype = np.dtype("uint64")
19-
warn1 = FutureWarning
20-
else:
21-
expected_dtype = np.dtype("int64")
22-
warn1 = None
23-
24-
msg_overflow = "will raise if the conversion overflows"
25-
with tm.assert_produces_warning(warn1, match=msg_overflow):
26-
expected = arr.astype(expected_dtype)
27-
28-
warn = None if dtype == expected_dtype else FutureWarning
29-
msg = " will return exactly the specified dtype"
30-
if warn is None and warn1 is not None:
31-
warn = warn1
32-
msg = msg_overflow
33-
with tm.assert_produces_warning(warn, match=msg):
34-
result = arr.astype(dtype)
35-
36-
assert result.dtype == expected_dtype
17+
if np.dtype(dtype) != np.int64:
18+
with pytest.raises(TypeError, match=r"Do obj.astype\('int64'\)"):
19+
arr.astype(dtype)
20+
return
21+
22+
result = arr.astype(dtype)
23+
expected = arr._ndarray.view("i8")
3724
tm.assert_numpy_array_equal(result, expected)
3825

3926

pandas/tests/arrays/test_datetimes.py

+6-13
Original file line numberDiff line numberDiff line change
@@ -377,20 +377,13 @@ def test_astype_copies(self, dtype, other):
377377
def test_astype_int(self, dtype):
378378
arr = DatetimeArray._from_sequence([pd.Timestamp("2000"), pd.Timestamp("2001")])
379379

380-
if np.dtype(dtype).kind == "u":
381-
expected_dtype = np.dtype("uint64")
382-
else:
383-
expected_dtype = np.dtype("int64")
384-
expected = arr.astype(expected_dtype)
385-
386-
warn = None
387-
if dtype != expected_dtype:
388-
warn = FutureWarning
389-
msg = " will return exactly the specified dtype"
390-
with tm.assert_produces_warning(warn, match=msg):
391-
result = arr.astype(dtype)
380+
if np.dtype(dtype) != np.int64:
381+
with pytest.raises(TypeError, match=r"Do obj.astype\('int64'\)"):
382+
arr.astype(dtype)
383+
return
392384

393-
assert result.dtype == expected_dtype
385+
result = arr.astype(dtype)
386+
expected = arr._ndarray.view("i8")
394387
tm.assert_numpy_array_equal(result, expected)
395388

396389
def test_astype_to_sparse_dt64(self):

pandas/tests/arrays/test_timedeltas.py

+7-14
Original file line numberDiff line numberDiff line change
@@ -190,20 +190,13 @@ class TestTimedeltaArray:
190190
def test_astype_int(self, dtype):
191191
arr = TimedeltaArray._from_sequence([Timedelta("1H"), Timedelta("2H")])
192192

193-
if np.dtype(dtype).kind == "u":
194-
expected_dtype = np.dtype("uint64")
195-
else:
196-
expected_dtype = np.dtype("int64")
197-
expected = arr.astype(expected_dtype)
198-
199-
warn = None
200-
if dtype != expected_dtype:
201-
warn = FutureWarning
202-
msg = " will return exactly the specified dtype"
203-
with tm.assert_produces_warning(warn, match=msg):
204-
result = arr.astype(dtype)
205-
206-
assert result.dtype == expected_dtype
193+
if np.dtype(dtype) != np.int64:
194+
with pytest.raises(TypeError, match=r"Do obj.astype\('int64'\)"):
195+
arr.astype(dtype)
196+
return
197+
198+
result = arr.astype(dtype)
199+
expected = arr._ndarray.view("i8")
207200
tm.assert_numpy_array_equal(result, expected)
208201

209202
def test_setitem_clears_freq(self):

pandas/tests/extension/test_arrow.py

+11
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
)
3636
from pandas.errors import PerformanceWarning
3737

38+
from pandas.core.dtypes.common import is_any_int_dtype
39+
3840
import pandas as pd
3941
import pandas._testing as tm
4042
from pandas.api.types import (
@@ -1459,6 +1461,15 @@ def test_is_integer_dtype(data):
14591461
assert not is_integer_dtype(data)
14601462

14611463

1464+
def test_is_any_integer_dtype(data):
1465+
# GH 50667
1466+
pa_type = data.dtype.pyarrow_dtype
1467+
if pa.types.is_integer(pa_type):
1468+
assert is_any_int_dtype(data)
1469+
else:
1470+
assert not is_any_int_dtype(data)
1471+
1472+
14621473
def test_is_signed_integer_dtype(data):
14631474
pa_type = data.dtype.pyarrow_dtype
14641475
if pa.types.is_signed_integer(pa_type):

pandas/tests/frame/test_unary.py

+21-5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import numpy as np
44
import pytest
55

6+
from pandas.compat import is_numpy_dev
7+
68
import pandas as pd
79
import pandas._testing as tm
810

@@ -98,11 +100,6 @@ def test_pos_numeric(self, df):
98100
@pytest.mark.parametrize(
99101
"df",
100102
[
101-
# numpy changing behavior in the future
102-
pytest.param(
103-
pd.DataFrame({"a": ["a", "b"]}),
104-
marks=[pytest.mark.filterwarnings("ignore")],
105-
),
106103
pd.DataFrame({"a": np.array([-1, 2], dtype=object)}),
107104
pd.DataFrame({"a": [Decimal("-1.0"), Decimal("2.0")]}),
108105
],
@@ -112,6 +109,25 @@ def test_pos_object(self, df):
112109
tm.assert_frame_equal(+df, df)
113110
tm.assert_series_equal(+df["a"], df["a"])
114111

112+
@pytest.mark.parametrize(
113+
"df",
114+
[
115+
pytest.param(
116+
pd.DataFrame({"a": ["a", "b"]}),
117+
marks=[pytest.mark.filterwarnings("ignore")],
118+
),
119+
],
120+
)
121+
def test_pos_object_raises(self, df):
122+
# GH#21380
123+
if is_numpy_dev:
124+
with pytest.raises(
125+
TypeError, match=r"^bad operand type for unary \+: \'str\'$"
126+
):
127+
tm.assert_frame_equal(+df, df)
128+
else:
129+
tm.assert_series_equal(+df["a"], df["a"])
130+
115131
@pytest.mark.parametrize(
116132
"df", [pd.DataFrame({"a": pd.to_datetime(["2017-01-22", "1970-01-01"])})]
117133
)

pandas/tests/indexes/datetimes/methods/test_astype.py

+5-13
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,7 @@
1515
date_range,
1616
)
1717
import pandas._testing as tm
18-
from pandas.core.api import (
19-
Int64Index,
20-
UInt64Index,
21-
)
18+
from pandas.core.api import Int64Index
2219

2320

2421
class TestDatetimeIndex:
@@ -47,16 +44,11 @@ def test_astype(self):
4744

4845
def test_astype_uint(self):
4946
arr = date_range("2000", periods=2, name="idx")
50-
expected = UInt64Index(
51-
np.array([946684800000000000, 946771200000000000], dtype="uint64"),
52-
name="idx",
53-
)
54-
tm.assert_index_equal(arr.astype("uint64"), expected)
5547

56-
msg = "will return exactly the specified dtype instead of uint64"
57-
with tm.assert_produces_warning(FutureWarning, match=msg):
58-
res = arr.astype("uint32")
59-
tm.assert_index_equal(res, expected)
48+
with pytest.raises(TypeError, match=r"Do obj.astype\('int64'\)"):
49+
arr.astype("uint64")
50+
with pytest.raises(TypeError, match=r"Do obj.astype\('int64'\)"):
51+
arr.astype("uint32")
6052

6153
def test_astype_with_tz(self):
6254

pandas/tests/indexes/interval/test_astype.py

+12-9
Original file line numberDiff line numberDiff line change
@@ -206,15 +206,18 @@ def index(self, request):
206206
def test_subtype_integer(self, index, subtype):
207207
dtype = IntervalDtype(subtype, "right")
208208

209-
warn = None
210-
if index.isna().any() and subtype == "uint64":
211-
warn = FutureWarning
212-
msg = "In a future version, this astype will raise if the conversion overflows"
213-
214-
with tm.assert_produces_warning(warn, match=msg):
215-
result = index.astype(dtype)
216-
new_left = index.left.astype(subtype)
217-
new_right = index.right.astype(subtype)
209+
if subtype != "int64":
210+
msg = (
211+
r"Cannot convert interval\[(timedelta64|datetime64)\[ns.*\], .*\] "
212+
r"to interval\[uint64, .*\]"
213+
)
214+
with pytest.raises(TypeError, match=msg):
215+
index.astype(dtype)
216+
return
217+
218+
result = index.astype(dtype)
219+
new_left = index.left.astype(subtype)
220+
new_right = index.right.astype(subtype)
218221

219222
expected = IntervalIndex.from_arrays(new_left, new_right, closed=index.closed)
220223
tm.assert_index_equal(result, expected)

pandas/tests/indexes/period/methods/test_astype.py

+5-10
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,7 @@
1111
period_range,
1212
)
1313
import pandas._testing as tm
14-
from pandas.core.indexes.api import (
15-
Int64Index,
16-
UInt64Index,
17-
)
14+
from pandas.core.indexes.api import Int64Index
1815

1916

2017
class TestPeriodIndexAsType:
@@ -55,13 +52,11 @@ def test_astype_conversion(self):
5552

5653
def test_astype_uint(self):
5754
arr = period_range("2000", periods=2, name="idx")
58-
expected = UInt64Index(np.array([10957, 10958], dtype="uint64"), name="idx")
59-
tm.assert_index_equal(arr.astype("uint64"), expected)
6055

61-
msg = "will return exactly the specified dtype instead of uint64"
62-
with tm.assert_produces_warning(FutureWarning, match=msg):
63-
res = arr.astype("uint32")
64-
tm.assert_index_equal(res, expected)
56+
with pytest.raises(TypeError, match=r"Do obj.astype\('int64'\)"):
57+
arr.astype("uint64")
58+
with pytest.raises(TypeError, match=r"Do obj.astype\('int64'\)"):
59+
arr.astype("uint32")
6560

6661
def test_astype_object(self):
6762
idx = PeriodIndex([], freq="M")

0 commit comments

Comments
 (0)