Skip to content

ENH: Implement PandasArray, DTA, TDA interpolate #53594

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions pandas/core/arrays/datetimelike.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@

from pandas.core import (
algorithms,
missing,
nanops,
)
from pandas.core.algorithms import (
Expand Down Expand Up @@ -142,6 +143,7 @@
from pandas.tseries import frequencies

if TYPE_CHECKING:
from pandas import Index
from pandas.core.arrays import (
DatetimeArray,
PeriodArray,
Expand Down Expand Up @@ -2228,6 +2230,46 @@ def copy(self, order: str = "C") -> Self:
new_obj._freq = self.freq
return new_obj

def interpolate(
self,
*,
method,
axis: int,
index: Index | None,
limit,
limit_direction,
limit_area,
fill_value,
inplace: bool,
**kwargs,
) -> Self:
"""
See NDFrame.interpolate.__doc__.
"""
# NB: we return type(self) even if inplace=True
if method != "linear":
raise NotImplementedError

if inplace:
out_data = self._ndarray
else:
out_data = self._ndarray.copy()

missing.interpolate_array_2d(
out_data,
method=method,
axis=axis,
index=index,
limit=limit,
limit_direction=limit_direction,
limit_area=limit_area,
fill_value=fill_value,
**kwargs,
)
if inplace:
return self
return type(self)._simple_new(out_data, dtype=self.dtype)


# -------------------------------------------------------------------
# Shared Constructor Helpers
Expand Down
41 changes: 41 additions & 0 deletions pandas/core/arrays/numpy_.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

from pandas.core import (
arraylike,
missing,
nanops,
ops,
)
Expand All @@ -33,9 +34,12 @@
Dtype,
NpDtype,
Scalar,
Self,
npt,
)

from pandas import Index


# error: Definition of "_concat_same_type" in base class "NDArrayBacked" is
# incompatible with definition in base class "ExtensionArray"
Expand Down Expand Up @@ -220,6 +224,43 @@ def _values_for_factorize(self) -> tuple[np.ndarray, float | None]:
fv = np.nan
return self._ndarray, fv

def interpolate(
self,
*,
method,
axis: int,
index: Index | None,
limit,
limit_direction,
limit_area,
fill_value,
inplace: bool,
**kwargs,
) -> Self:
"""
See NDFrame.interpolate.__doc__.
"""
# NB: we return type(self) even if inplace=True
if inplace:
out_data = self._ndarray
else:
out_data = self._ndarray.copy()

missing.interpolate_array_2d(
out_data,
method=method,
axis=axis,
index=index,
limit=limit,
limit_direction=limit_direction,
limit_area=limit_area,
fill_value=fill_value,
**kwargs,
)
if inplace:
return self
return type(self)._simple_new(out_data, dtype=self.dtype)

# ------------------------------------------------------------------------
# Reductions

Expand Down
32 changes: 18 additions & 14 deletions pandas/core/internals/blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -1394,27 +1394,27 @@ def interpolate(
)

refs = None
arr_inplace = inplace
if inplace:
if using_cow and self.refs.has_reference():
data = self.values.copy()
arr_inplace = False
else:
data = self.values
refs = self.refs
else:
data = self.values.copy()
data = cast(np.ndarray, data) # bc overridden by ExtensionBlock

missing.interpolate_array_2d(
data,
# Dispatch to the PandasArray method.
# We know self.array_values is a PandasArray bc EABlock overrides
new_values = cast(PandasArray, self.array_values).interpolate(
method=method,
axis=axis,
index=index,
limit=limit,
limit_direction=limit_direction,
limit_area=limit_area,
fill_value=fill_value,
inplace=arr_inplace,
**kwargs,
)
data = new_values._ndarray

nb = self.make_block_same_class(data, refs=refs)
return nb._maybe_downcast([nb], downcast, using_cow)
Expand Down Expand Up @@ -2262,18 +2262,22 @@ def interpolate(
if method == "linear": # type: ignore[comparison-overlap]
# TODO: GH#50950 implement for arbitrary EAs
refs = None
arr_inplace = inplace
if using_cow:
if inplace and not self.refs.has_reference():
data_out = values._ndarray
refs = self.refs
else:
data_out = values._ndarray.copy()
else:
data_out = values._ndarray if inplace else values._ndarray.copy()
missing.interpolate_array_2d(
data_out, method=method, limit=limit, index=index, axis=axis
arr_inplace = False

new_values = self.values.interpolate(
method=method,
index=index,
axis=axis,
inplace=arr_inplace,
limit=limit,
fill_value=fill_value,
**kwargs,
)
new_values = type(values)._simple_new(data_out, dtype=values.dtype)
return self.make_block_same_class(new_values, refs=refs)

elif values.ndim == 2 and axis == 0:
Expand Down