Skip to content

Commit

Permalink
Merge pull request pandas-dev#11 from jbrockmendel/na
Browse files Browse the repository at this point in the history
Restore locations of null-handing methods
  • Loading branch information
TomAugspurger authored Dec 30, 2018
2 parents 695010c + a32e020 commit 6d2fc99
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 59 deletions.
104 changes: 52 additions & 52 deletions pandas/core/arrays/datetimelike.py
Original file line number Diff line number Diff line change
Expand Up @@ -535,58 +535,6 @@ def _maybe_clear_freq(self):
# DatetimeArray and TimedeltaArray
pass

def isna(self):
return self._isnan

@property # NB: override with cache_readonly in immutable subclasses
def _isnan(self):
"""
return if each value is nan
"""
return (self.asi8 == iNaT)

@property # NB: override with cache_readonly in immutable subclasses
def _hasnans(self):
"""
return if I have any nans; enables various perf speedups
"""
return bool(self._isnan.any())

def fillna(self, value=None, method=None, limit=None):
# TODO(GH-20300): remove this
# Just overriding to ensure that we avoid an astype(object).
# Either 20300 or a `_values_for_fillna` would avoid this duplication.
if isinstance(value, ABCSeries):
value = value.array

value, method = validate_fillna_kwargs(value, method)

mask = self.isna()

if is_array_like(value):
if len(value) != len(self):
raise ValueError("Length of 'value' does not match. Got ({}) "
" expected {}".format(len(value), len(self)))
value = value[mask]

if mask.any():
if method is not None:
if method == 'pad':
func = missing.pad_1d
else:
func = missing.backfill_1d

new_values = func(self._data, limit=limit,
mask=mask)
new_values = type(self)(new_values, dtype=self.dtype)
else:
# fill with value
new_values = self.copy()
new_values[mask] = value
else:
new_values = self.copy()
return new_values

def astype(self, dtype, copy=True):
# Some notes on cases we don't have to handle here in the base class:
# 1. PeriodArray.astype handles period -> period
Expand Down Expand Up @@ -800,6 +748,23 @@ def map(self, mapper):
# ------------------------------------------------------------------
# Null Handling

def isna(self):
return self._isnan

@property # NB: override with cache_readonly in immutable subclasses
def _isnan(self):
"""
return if each value is nan
"""
return (self.asi8 == iNaT)

@property # NB: override with cache_readonly in immutable subclasses
def _hasnans(self):
"""
return if I have any nans; enables various perf speedups
"""
return bool(self._isnan.any())

def _maybe_mask_results(self, result, fill_value=iNaT, convert=None):
"""
Parameters
Expand All @@ -826,6 +791,41 @@ def _maybe_mask_results(self, result, fill_value=iNaT, convert=None):
result[self._isnan] = fill_value
return result

def fillna(self, value=None, method=None, limit=None):
# TODO(GH-20300): remove this
# Just overriding to ensure that we avoid an astype(object).
# Either 20300 or a `_values_for_fillna` would avoid this duplication.
if isinstance(value, ABCSeries):
value = value.array

value, method = validate_fillna_kwargs(value, method)

mask = self.isna()

if is_array_like(value):
if len(value) != len(self):
raise ValueError("Length of 'value' does not match. Got ({}) "
" expected {}".format(len(value), len(self)))
value = value[mask]

if mask.any():
if method is not None:
if method == 'pad':
func = missing.pad_1d
else:
func = missing.backfill_1d

new_values = func(self._data, limit=limit,
mask=mask)
new_values = type(self)(new_values, dtype=self.dtype)
else:
# fill with value
new_values = self.copy()
new_values[mask] = value
else:
new_values = self.copy()
return new_values

# ------------------------------------------------------------------
# Frequency Properties/Methods

Expand Down
4 changes: 2 additions & 2 deletions pandas/core/arrays/timedeltas.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,8 +259,8 @@ def _generate_range(cls, start, end, periods, freq, closed=None):
# DatetimeLike Interface

def _unbox_scalar(self, value):
if not isinstance(value, (self._scalar_type, type(NaT))):
raise ValueError("'value' should be a a Timestamp.")
if not isinstance(value, self._scalar_type) and value is not NaT:
raise ValueError("'value' should be a Timedelta.")
self._check_compatible_with(value)
return value.value

Expand Down
4 changes: 2 additions & 2 deletions pandas/core/indexes/timedeltas.py
Original file line number Diff line number Diff line change
Expand Up @@ -345,8 +345,8 @@ def astype(self, dtype, copy=True):
dtype = pandas_dtype(dtype)
if is_timedelta64_dtype(dtype) and not is_timedelta64_ns_dtype(dtype):
# Have to repeat the check for 'timedelta64' (not ns) dtype
# so that we can return a numeric index, since pandas will return
# a TimedeltaIndex when dtype='timedelta'
# so that we can return a numeric index, since pandas will return
# a TimedeltaIndex when dtype='timedelta'
result = self._data.astype(dtype, copy=copy)
if self.hasnans:
return Index(result, name=self.name)
Expand Down
2 changes: 1 addition & 1 deletion pandas/tests/arithmetic/test_datetime64.py
Original file line number Diff line number Diff line change
Expand Up @@ -1981,7 +1981,7 @@ def test_dti_sub_tdi(self, tz_naive_fixture):
result = dti - tdi
tm.assert_index_equal(result, expected)

msg = 'cannot subtract .*TimedeltaArray'
msg = 'cannot subtract .*TimedeltaArrayMixin'
with pytest.raises(TypeError, match=msg):
tdi - dti

Expand Down
2 changes: 1 addition & 1 deletion pandas/tests/indexes/datetimes/test_astype.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ def test_astype_object_with_nat(self):
def test_astype_raises(self, dtype):
# GH 13149, GH 13209
idx = DatetimeIndex(['2016-05-16', 'NaT', NaT, np.NaN])
msg = 'Cannot cast DatetimeArray(Mixin)? to dtype'
msg = 'Cannot cast DatetimeArrayMixin to dtype'
with pytest.raises(TypeError, match=msg):
idx.astype(dtype)

Expand Down
2 changes: 1 addition & 1 deletion pandas/tests/indexes/timedeltas/test_astype.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ def test_astype_timedelta64(self):
def test_astype_raises(self, dtype):
# GH 13149, GH 13209
idx = TimedeltaIndex([1e14, 'NaT', NaT, np.NaN])
msg = 'Cannot cast TimedeltaArray(Mixin)? to dtype'
msg = 'Cannot cast TimedeltaArrayMixin to dtype'
with pytest.raises(TypeError, match=msg):
idx.astype(dtype)

Expand Down

0 comments on commit 6d2fc99

Please sign in to comment.