Skip to content

Commit 8bcd3dc

Browse files
Merge branch 'pandas-dev:main' into ordered_cat_corr
2 parents 4184167 + c6ca221 commit 8bcd3dc

File tree

9 files changed

+65
-17
lines changed

9 files changed

+65
-17
lines changed

doc/source/whatsnew/v3.0.0.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1112,6 +1112,7 @@ Conversion
11121112
- Bug in :meth:`DataFrame.astype` not casting ``values`` for Arrow-based dictionary dtype correctly (:issue:`58479`)
11131113
- Bug in :meth:`DataFrame.update` bool dtype being converted to object (:issue:`55509`)
11141114
- Bug in :meth:`Series.astype` might modify read-only array inplace when casting to a string dtype (:issue:`57212`)
1115+
- Bug in :meth:`Series.convert_dtypes` and :meth:`DataFrame.convert_dtypes` raising ``TypeError`` when called on data with complex dtype (:issue:`60129`)
11151116
- Bug in :meth:`Series.convert_dtypes` and :meth:`DataFrame.convert_dtypes` removing timezone information for objects with :class:`ArrowDtype` (:issue:`60237`)
11161117
- Bug in :meth:`Series.reindex` not maintaining ``float32`` type when a ``reindex`` introduces a missing value (:issue:`45857`)
11171118
- Bug in :meth:`to_datetime` and :meth:`to_timedelta` with input ``None`` returning ``None`` instead of ``NaT``, inconsistent with other conversion methods (:issue:`23055`)
@@ -1128,6 +1129,7 @@ Interval
11281129
- :meth:`Index.is_monotonic_decreasing`, :meth:`Index.is_monotonic_increasing`, and :meth:`Index.is_unique` could incorrectly be ``False`` for an ``Index`` created from a slice of another ``Index``. (:issue:`57911`)
11291130
- Bug in :class:`Index`, :class:`Series`, :class:`DataFrame` constructors when given a sequence of :class:`Interval` subclass objects casting them to :class:`Interval` (:issue:`46945`)
11301131
- Bug in :func:`interval_range` where start and end numeric types were always cast to 64 bit (:issue:`57268`)
1132+
- Bug in :func:`pandas.interval_range` incorrectly inferring ``int64`` dtype when ``np.float32`` and ``int`` are used for ``start`` and ``freq`` (:issue:`58964`)
11311133
- Bug in :meth:`IntervalIndex.get_indexer` and :meth:`IntervalIndex.drop` when one of the sides of the index is non-unique (:issue:`52245`)
11321134
- Construction of :class:`IntervalArray` and :class:`IntervalIndex` from arrays with mismatched signed/unsigned integer dtypes (e.g., ``int64`` and ``uint64``) now raises a :exc:`TypeError` instead of proceeding silently. (:issue:`55715`)
11331135

pandas/core/dtypes/cast.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -934,6 +934,9 @@ def convert_dtypes(
934934
if (
935935
convert_string or convert_integer or convert_boolean or convert_floating
936936
) and isinstance(input_array, np.ndarray):
937+
if input_array.dtype.kind == "c":
938+
return input_array.dtype
939+
937940
if input_array.dtype == object:
938941
inferred_dtype = lib.infer_dtype(input_array)
939942
else:
@@ -954,7 +957,7 @@ def convert_dtypes(
954957
inferred_dtype = NUMPY_INT_TO_DTYPE.get(
955958
input_array.dtype, target_int_dtype
956959
)
957-
elif input_array.dtype.kind in "fcb":
960+
elif input_array.dtype.kind in "fb":
958961
# TODO: de-dup with maybe_cast_to_integer_array?
959962
arr = input_array[notna(input_array)]
960963
if len(arr) < len(input_array) and not is_nan_na():
@@ -972,7 +975,7 @@ def convert_dtypes(
972975
inferred_dtype = target_int_dtype
973976

974977
if convert_floating:
975-
if input_array.dtype.kind in "fcb":
978+
if input_array.dtype.kind in "fb":
976979
# i.e. numeric but not integer
977980
from pandas.core.arrays.floating import NUMPY_FLOAT_TO_DTYPE
978981

@@ -1028,11 +1031,11 @@ def convert_dtypes(
10281031

10291032
if (
10301033
(convert_integer and inferred_dtype.kind in "iu")
1031-
or (convert_floating and inferred_dtype.kind in "fc")
1034+
or (convert_floating and inferred_dtype.kind in "f")
10321035
or (convert_boolean and inferred_dtype.kind == "b")
10331036
or (convert_string and isinstance(inferred_dtype, StringDtype))
10341037
or (
1035-
inferred_dtype.kind not in "iufcb"
1038+
inferred_dtype.kind not in "iufb"
10361039
and not isinstance(inferred_dtype, StringDtype)
10371040
and not isinstance(inferred_dtype, CategoricalDtype)
10381041
)

pandas/core/indexes/interval.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1420,17 +1420,17 @@ def interval_range(
14201420
dtype: np.dtype = np.dtype("int64")
14211421
if com.all_not_none(start, end, freq):
14221422
if (
1423-
isinstance(start, (float, np.float16))
1424-
or isinstance(end, (float, np.float16))
1425-
or isinstance(freq, (float, np.float16))
1426-
):
1427-
dtype = np.dtype("float64")
1428-
elif (
14291423
isinstance(start, (np.integer, np.floating))
14301424
and isinstance(end, (np.integer, np.floating))
14311425
and start.dtype == end.dtype
14321426
):
14331427
dtype = start.dtype
1428+
elif (
1429+
isinstance(start, (float, np.floating))
1430+
or isinstance(end, (float, np.floating))
1431+
or isinstance(freq, (float, np.floating))
1432+
):
1433+
dtype = np.dtype("float64")
14341434
# 0.1 ensures we capture end
14351435
breaks = np.arange(start, end + (freq * 0.1), freq)
14361436
breaks = maybe_downcast_numeric(breaks, dtype)

pandas/tests/frame/methods/test_convert_dtypes.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,3 +228,15 @@ def test_convert_dtype_pyarrow_timezone_preserve(self):
228228
result = df.convert_dtypes(dtype_backend="pyarrow")
229229
expected = df.copy()
230230
tm.assert_frame_equal(result, expected)
231+
232+
def test_convert_dtypes_complex(self):
233+
# GH 60129
234+
df = pd.DataFrame({"a": [1.0 + 5.0j, 1.5 - 3.0j], "b": [1, 2]})
235+
expected = pd.DataFrame(
236+
{
237+
"a": pd.array([1.0 + 5.0j, 1.5 - 3.0j], dtype="complex128"),
238+
"b": pd.array([1, 2], dtype="Int64"),
239+
}
240+
)
241+
result = df.convert_dtypes()
242+
tm.assert_frame_equal(result, expected)

pandas/tests/frame/methods/test_rename_axis.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,18 @@ def test_rename_axis_inplace(self, float_frame):
2828
assert no_return is None
2929
tm.assert_frame_equal(result, expected)
3030

31+
def test_rename_axis_with_allows_duplicate_labels_false(self):
32+
# GH#44958
33+
df = DataFrame([[1, 2], [3, 4]], columns=["a", "b"]).set_flags(
34+
allows_duplicate_labels=False
35+
)
36+
37+
result = df.rename_axis("idx", axis=0)
38+
expected = DataFrame(
39+
[[1, 2], [3, 4]], index=Index([0, 1], name="idx"), columns=["a", "b"]
40+
)
41+
tm.assert_frame_equal(result, expected, check_flags=False)
42+
3143
def test_rename_axis_raises(self):
3244
# GH#17833
3345
df = DataFrame({"A": [1, 2], "B": [1, 2]})

pandas/tests/frame/methods/test_set_axis.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,16 @@ def obj(self):
112112
)
113113
return df
114114

115+
def test_set_axis_with_allows_duplicate_labels_false(self):
116+
# GH#44958
117+
df = DataFrame([[1, 2], [3, 4]], columns=["a", "b"]).set_flags(
118+
allows_duplicate_labels=False
119+
)
120+
121+
result = df.set_axis(labels=["x", "y"], axis=0)
122+
expected = DataFrame([[1, 2], [3, 4]], index=["x", "y"], columns=["a", "b"])
123+
tm.assert_frame_equal(result, expected, check_flags=False)
124+
115125

116126
class TestSeriesSetAxis(SharedSetAxisTests):
117127
@pytest.fixture

pandas/tests/indexes/interval/test_interval_range.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,3 +380,11 @@ def test_float_freq(self):
380380
result = interval_range(0, 1, freq=0.6)
381381
expected = IntervalIndex.from_breaks([0, 0.6])
382382
tm.assert_index_equal(result, expected)
383+
384+
def test_interval_range_float32_start_int_freq(self):
385+
# GH 58964
386+
result = interval_range(start=np.float32(0), end=2, freq=1)
387+
expected = IntervalIndex.from_tuples(
388+
[(0.0, 1.0), (1.0, 2.0)], dtype="interval[float64, right]"
389+
)
390+
tm.assert_index_equal(result, expected)

pandas/tests/io/parser/test_na_values.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -499,13 +499,8 @@ def test_na_values_scalar(all_parsers, na_values, row_data):
499499
data = "1,2\n2,1"
500500

501501
if parser.engine == "pyarrow" and isinstance(na_values, dict):
502-
if isinstance(na_values, dict):
503-
err = ValueError
504-
msg = "The pyarrow engine doesn't support passing a dict for na_values"
505-
else:
506-
err = TypeError
507-
msg = "The 'pyarrow' engine requires all na_values to be strings"
508-
with pytest.raises(err, match=msg):
502+
msg = "The pyarrow engine doesn't support passing a dict for na_values"
503+
with pytest.raises(ValueError, match=msg):
509504
parser.read_csv(StringIO(data), names=names, na_values=na_values)
510505
return
511506
elif parser.engine == "pyarrow":

pandas/tests/series/methods/test_convert_dtypes.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,3 +332,9 @@ def test_convert_dtype_pyarrow_timezone_preserve(self):
332332
result = ser.convert_dtypes(dtype_backend="pyarrow")
333333
expected = ser.copy()
334334
tm.assert_series_equal(result, expected)
335+
336+
def test_convert_dtypes_complex(self):
337+
# GH 60129
338+
ser = pd.Series([1.5 + 3.0j, 1.5 - 3.0j])
339+
result = ser.convert_dtypes()
340+
tm.assert_series_equal(result, ser)

0 commit comments

Comments
 (0)