Skip to content

Commit 3402233

Browse files
authored
Closes #36541 (BUG: ValueError: cannot convert float NaN to integer when resetting MultiIndex with NaT values) (#36563)
1 parent 697cca7 commit 3402233

File tree

3 files changed

+36
-1
lines changed

3 files changed

+36
-1
lines changed

doc/source/whatsnew/v1.2.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,7 @@ MultiIndex
375375
^^^^^^^^^^
376376

377377
- Bug in :meth:`DataFrame.xs` when used with :class:`IndexSlice` raises ``TypeError`` with message ``"Expected label or tuple of labels"`` (:issue:`35301`)
378+
- Bug in :meth:`DataFrame.reset_index` with ``NaT`` values in index raises ``ValueError`` with message ``"cannot convert float NaN to integer"`` (:issue:`36541`)
378379
-
379380

380381
I/O

pandas/core/dtypes/cast.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@
7373
ABCSeries,
7474
)
7575
from pandas.core.dtypes.inference import is_list_like
76-
from pandas.core.dtypes.missing import isna, notna
76+
from pandas.core.dtypes.missing import is_valid_nat_for_dtype, isna, notna
7777

7878
if TYPE_CHECKING:
7979
from pandas import Series
@@ -1559,6 +1559,11 @@ def construct_1d_arraylike_from_scalar(
15591559
dtype = np.dtype("object")
15601560
if not isna(value):
15611561
value = ensure_str(value)
1562+
elif dtype.kind in ["M", "m"] and is_valid_nat_for_dtype(value, dtype):
1563+
# GH36541: can't fill array directly with pd.NaT
1564+
# > np.empty(10, dtype="datetime64[64]").fill(pd.NaT)
1565+
# ValueError: cannot convert float NaN to integer
1566+
value = np.datetime64("NaT")
15621567

15631568
subarr = np.empty(length, dtype=dtype)
15641569
subarr.fill(value)

pandas/tests/series/indexing/test_multiindex.py

+29
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
""" test get/set & misc """
22

3+
import pytest
34

45
import pandas as pd
56
from pandas import MultiIndex, Series
7+
import pandas._testing as tm
68

79

810
def test_access_none_value_in_multiindex():
@@ -20,3 +22,30 @@ def test_access_none_value_in_multiindex():
2022
s = Series([1] * len(midx), dtype=object, index=midx)
2123
result = s.loc[("Level1", "Level2_a")]
2224
assert result == 1
25+
26+
27+
@pytest.mark.parametrize(
28+
"ix_data, exp_data",
29+
[
30+
(
31+
[(pd.NaT, 1), (pd.NaT, 2)],
32+
{"a": [pd.NaT, pd.NaT], "b": [1, 2], "x": [11, 12]},
33+
),
34+
(
35+
[(pd.NaT, 1), (pd.Timestamp("2020-01-01"), 2)],
36+
{"a": [pd.NaT, pd.Timestamp("2020-01-01")], "b": [1, 2], "x": [11, 12]},
37+
),
38+
(
39+
[(pd.NaT, 1), (pd.Timedelta(123, "d"), 2)],
40+
{"a": [pd.NaT, pd.Timedelta(123, "d")], "b": [1, 2], "x": [11, 12]},
41+
),
42+
],
43+
)
44+
def test_nat_multi_index(ix_data, exp_data):
45+
# GH36541: that reset_index() does not raise ValueError
46+
ix = pd.MultiIndex.from_tuples(ix_data, names=["a", "b"])
47+
result = pd.DataFrame({"x": [11, 12]}, index=ix)
48+
result = result.reset_index()
49+
50+
expected = pd.DataFrame(exp_data)
51+
tm.assert_frame_equal(result, expected)

0 commit comments

Comments
 (0)