|
28 | 28 | from pandas.core import config
|
29 | 29 | from pandas.core.categorical import Categorical
|
30 | 30 |
|
| 31 | +from itertools import product |
| 32 | + |
31 | 33 | # goal is to be able to define the docs close to function, while still being
|
32 | 34 | # able to share
|
33 | 35 | _shared_docs = dict()
|
@@ -2290,31 +2292,25 @@ def fillna(self, value=None, method=None, axis=None, inplace=False,
|
2290 | 2292 |
|
2291 | 2293 | method = com._clean_fill_method(method)
|
2292 | 2294 |
|
2293 |
| - def interp_func(series): |
2294 |
| - return series._data.interpolate(method=method, |
2295 |
| - inplace=inplace, |
2296 |
| - limit=limit, |
2297 |
| - coerce=True, |
2298 |
| - downcast=downcast) |
2299 |
| - if self.ndim > 1: |
2300 |
| - if inplace: |
2301 |
| - self.apply(interp_func, axis=axis) |
2302 |
| - new_data = self._data |
2303 |
| - else: |
2304 |
| - cats = None |
2305 |
| - if self._is_mixed_type: |
2306 |
| - cats = self._get_cats() |
2307 |
| - |
2308 |
| - result = self.apply(lambda s: s.fillna(method=method, |
2309 |
| - limit=limit, |
2310 |
| - downcast=downcast), |
2311 |
| - axis=axis) |
2312 |
| - result = result.convert_objects(copy=False) |
2313 |
| - if cats: |
2314 |
| - result._restore_cats(cats) |
2315 |
| - new_data = result._data |
2316 |
| - else: |
2317 |
| - new_data = interp_func(self) |
| 2295 | + off_axes = list(range(self.ndim)) |
| 2296 | + off_axes.remove(axis) |
| 2297 | + expanded = [list(range(self.shape[x])) for x in off_axes] |
| 2298 | + frame = self if inplace else self.copy() |
| 2299 | + for axes_prod in product(*expanded): |
| 2300 | + slicer = list(axes_prod) |
| 2301 | + slicer.insert(axis, slice(None)) |
| 2302 | + sl = tuple(slicer) |
| 2303 | + piece = frame.iloc[sl] |
| 2304 | + new_data = piece._data.interpolate(method=method, |
| 2305 | + limit=limit, |
| 2306 | + inplace=True, |
| 2307 | + coerce=True) |
| 2308 | + frame.iloc[sl] = piece._constructor(new_data) |
| 2309 | + |
| 2310 | + new_data = frame._data |
| 2311 | + if downcast: |
| 2312 | + new_data = new_data.downcast(dtypes=downcast) |
| 2313 | + |
2318 | 2314 | else:
|
2319 | 2315 | if method is not None:
|
2320 | 2316 | raise ValueError('cannot specify both a fill method and value')
|
@@ -2368,22 +2364,6 @@ def interp_func(series):
|
2368 | 2364 | else:
|
2369 | 2365 | return self._constructor(new_data).__finalize__(self)
|
2370 | 2366 |
|
2371 |
| - def _get_cats(self): |
2372 |
| - if self._stat_axis_number == 0: |
2373 |
| - return dict((pt, self[pt].cat) for pt in self if |
2374 |
| - isinstance(self[pt].dtype, CategoricalDtype)) |
2375 |
| - else: |
2376 |
| - return dict((pt, self[pt]._get_cats()) for pt in self) |
2377 |
| - |
2378 |
| - def _restore_cats(self, cats): |
2379 |
| - for pt, sub in cats.items(): |
2380 |
| - if isinstance(sub, dict): |
2381 |
| - self[pt]._restore_cats(sub) |
2382 |
| - else: |
2383 |
| - self[pt] = Categorical(self[pt], |
2384 |
| - categories=sub.categories, |
2385 |
| - ordered=sub.ordered) |
2386 |
| - |
2387 | 2367 | def ffill(self, axis=None, inplace=False, limit=None, downcast=None):
|
2388 | 2368 | "Synonym for NDFrame.fillna(method='ffill')"
|
2389 | 2369 | return self.fillna(method='ffill', axis=axis, inplace=inplace,
|
|
0 commit comments