def _interpolate_with_fill(self, method='pad', axis=0, inplace=False, limit=None, fill_value=None, coerce=False, downcast=None): """ fillna but using the interpolate machinery """ # if we are coercing, then don't force the conversion # if the block can't hold the type if coerce: if not self._can_hold_na: if inplace: return [self] else: return [self.copy()] fill_value = self._try_fill(fill_value) values = self.values if inplace else self.values.copy() values = self._try_operate(values) values = com.interpolate_2d(values, method=method, axis=axis, limit=limit, fill_value=fill_value, dtype=self.dtype) values = self._try_coerce_result(values) blocks = [make_block(values, ndim=self.ndim, klass=self.__class__, fastpath=True, placement=self.mgr_locs)] return self._maybe_downcast(blocks, downcast)
def fillna(self, fill_value=None, method=None, limit=None, **kwargs): """ Fill NA/NaN values using the specified method. Parameters ---------- method : {'backfill', 'bfill', 'pad', 'ffill', None}, default None Method to use for filling holes in reindexed Series pad / ffill: propagate last valid observation forward to next valid backfill / bfill: use NEXT valid observation to fill gap value : scalar Value to use to fill holes (e.g. 0) limit : int, default None Maximum size gap to forward or backward fill (not implemented yet!) Returns ------- filled : Categorical with NA/NaN filled """ if fill_value is None: fill_value = np.nan if limit is not None: raise NotImplementedError values = self._codes # Make sure that we also get NA in levels if self.levels.dtype.kind in ['S', 'O', 'f']: if np.nan in self.levels: values = values.copy() nan_pos = np.where(isnull(self.levels))[0] # we only have one NA in levels values[values == nan_pos] = -1 # pad / bfill if method is not None: values = self.to_dense().reshape(-1, len(self)) values = com.interpolate_2d(values, method, 0, None, fill_value).astype( self.levels.dtype)[0] values = _get_codes_for_values(values, self.levels) else: if not com.isnull(fill_value) and fill_value not in self.levels: raise ValueError("fill value must be in levels") mask = values == -1 if mask.any(): values = values.copy() values[mask] = self.levels.get_loc(fill_value) return Categorical(values, levels=self.levels, ordered=self.ordered, name=self.name, fastpath=True)
def fillna(self, fill_value=None, method=None, limit=None, **kwargs): """ Fill NA/NaN values using the specified method. Parameters ---------- method : {'backfill', 'bfill', 'pad', 'ffill', None}, default None Method to use for filling holes in reindexed Series pad / ffill: propagate last valid observation forward to next valid backfill / bfill: use NEXT valid observation to fill gap value : scalar Value to use to fill holes (e.g. 0) limit : int, default None Maximum size gap to forward or backward fill (not implemented yet!) Returns ------- filled : Categorical with NA/NaN filled """ if fill_value is None: fill_value = np.nan if limit is not None: raise NotImplementedError values = self._codes # Make sure that we also get NA in categories if self.categories.dtype.kind in ['S', 'O', 'f']: if np.nan in self.categories: values = values.copy() nan_pos = np.where(isnull(self.categories))[0] # we only have one NA in categories values[values == nan_pos] = -1 # pad / bfill if method is not None: values = self.to_dense().reshape(-1,len(self)) values = com.interpolate_2d( values, method, 0, None, fill_value).astype(self.categories.dtype)[0] values = _get_codes_for_values(values, self.categories) else: if not com.isnull(fill_value) and fill_value not in self.categories: raise ValueError("fill value must be in categories") mask = values==-1 if mask.any(): values = values.copy() values[mask] = self.categories.get_loc(fill_value) return Categorical(values, categories=self.categories, ordered=self.ordered, name=self.name, fastpath=True)