Skip to content

Commit fc73758

Browse files
authored
BUG: DataFrame.interpolate failing to return a copy (#45791)
1 parent d0a687c commit fc73758

File tree

4 files changed

+43
-13
lines changed

4 files changed

+43
-13
lines changed

doc/source/whatsnew/v1.5.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ Indexing
282282
Missing
283283
^^^^^^^
284284
- Bug in :meth:`Series.fillna` and :meth:`DataFrame.fillna` with ``downcast`` keyword not being respected in some cases where there are no NA values present (:issue:`45423`)
285+
- Bug in :meth:`DataFrame.interpolate` with object-dtype column not returning a copy with ``inplace=False`` (:issue:`45791`)
285286
-
286287

287288
MultiIndex

pandas/core/generic.py

-1
Original file line numberDiff line numberDiff line change
@@ -6448,7 +6448,6 @@ def fillna(
64486448
axis=axis,
64496449
limit=limit,
64506450
inplace=inplace,
6451-
coerce=True,
64526451
downcast=downcast,
64536452
)
64546453
else:

pandas/core/internals/blocks.py

+10-12
Original file line numberDiff line numberDiff line change
@@ -1024,7 +1024,6 @@ def interpolate(
10241024
limit_direction: str = "forward",
10251025
limit_area: str | None = None,
10261026
fill_value: Any | None = None,
1027-
coerce: bool = False,
10281027
downcast: str | None = None,
10291028
**kwargs,
10301029
) -> list[Block]:
@@ -1035,6 +1034,16 @@ def interpolate(
10351034
# If there are no NAs, then interpolate is a no-op
10361035
return [self] if inplace else [self.copy()]
10371036

1037+
try:
1038+
m = missing.clean_fill_method(method)
1039+
except ValueError:
1040+
m = None
1041+
if m is None and self.dtype.kind != "f":
1042+
# only deal with floats
1043+
# bc we already checked that can_hold_na, we dont have int dtype here
1044+
# test_interp_basic checks that we make a copy here
1045+
return [self] if inplace else [self.copy()]
1046+
10381047
if self.is_object and self.ndim == 2 and self.shape[0] != 1 and axis == 0:
10391048
# split improves performance in ndarray.copy()
10401049
return self.split_and_operate(
@@ -1047,21 +1056,10 @@ def interpolate(
10471056
limit_direction,
10481057
limit_area,
10491058
fill_value,
1050-
coerce,
10511059
downcast,
10521060
**kwargs,
10531061
)
10541062

1055-
try:
1056-
m = missing.clean_fill_method(method)
1057-
except ValueError:
1058-
m = None
1059-
if m is None and self.dtype.kind != "f":
1060-
# only deal with floats
1061-
# bc we already checked that can_hold_na, we dont have int dtype here
1062-
# TODO: make a copy if not inplace?
1063-
return [self]
1064-
10651063
data = self.values if inplace else self.values.copy()
10661064
data = cast(np.ndarray, data) # bc overridden by ExtensionBlock
10671065

pandas/tests/frame/methods/test_interpolate.py

+32
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,38 @@ def test_interp_basic(self):
4949
result = df.interpolate()
5050
tm.assert_frame_equal(result, expected)
5151

52+
# check we didn't operate inplace GH#45791
53+
cvalues = df["C"]._values
54+
dvalues = df["D"].values
55+
assert not np.shares_memory(cvalues, result["C"]._values)
56+
assert not np.shares_memory(dvalues, result["D"]._values)
57+
58+
res = df.interpolate(inplace=True)
59+
assert res is None
60+
tm.assert_frame_equal(df, expected)
61+
62+
# check we DID operate inplace
63+
assert np.shares_memory(df["C"]._values, cvalues)
64+
assert np.shares_memory(df["D"]._values, dvalues)
65+
66+
def test_interp_basic_with_non_range_index(self):
67+
df = DataFrame(
68+
{
69+
"A": [1, 2, np.nan, 4],
70+
"B": [1, 4, 9, np.nan],
71+
"C": [1, 2, 3, 5],
72+
"D": list("abcd"),
73+
}
74+
)
75+
expected = DataFrame(
76+
{
77+
"A": [1.0, 2.0, 3.0, 4.0],
78+
"B": [1.0, 4.0, 9.0, 9.0],
79+
"C": [1, 2, 3, 5],
80+
"D": list("abcd"),
81+
}
82+
)
83+
5284
result = df.set_index("C").interpolate()
5385
expected = df.set_index("C")
5486
expected.loc[3, "A"] = 3

0 commit comments

Comments
 (0)