diff --git a/ci/script.sh b/ci/script.sh index 152a2f1ebdcf9..e76789b689c94 100755 --- a/ci/script.sh +++ b/ci/script.sh @@ -16,6 +16,13 @@ fi "$TRAVIS_BUILD_DIR"/ci/build_docs.sh 2>&1 > /tmp/doc.log & # doc build log will be shown after tests +# export the testing mode +if [ -n "$NUMPY_BUILD" ]; then + + export PANDAS_TESTING_MODE="numpy_deprecate" + +fi + echo nosetests --exe -w /tmp -A "$NOSE_ARGS" pandas --with-xunit --xunit-file=/tmp/nosetests.xml nosetests --exe -w /tmp -A "$NOSE_ARGS" pandas --with-xunit --xunit-file=/tmp/nosetests.xml diff --git a/doc/source/release.rst b/doc/source/release.rst index c975143b0ef67..f7b47b06ef841 100644 --- a/doc/source/release.rst +++ b/doc/source/release.rst @@ -240,6 +240,9 @@ Prior Version Deprecations/Changes - Remove ``time_rule`` from several rolling-moment statistical functions, such as :func:`rolling_sum` (:issue:`1042`) +- Removed neg (-) boolean operations on numpy arrays in favor of inv (~), as this is going to + be deprecated in numpy 1.9 (:issue:`6960`) + Experimental Features ~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/source/v0.14.0.txt b/doc/source/v0.14.0.txt index 34480668df8c9..dd6a21ccecf55 100644 --- a/doc/source/v0.14.0.txt +++ b/doc/source/v0.14.0.txt @@ -368,6 +368,8 @@ There are prior version deprecations that are taking effect as of 0.14.0. ( `commit 3136390 `__ ) - Remove ``time_rule`` from several rolling-moment statistical functions, such as :func:`rolling_sum` (:issue:`1042`) +- Removed neg (-) boolean operations on numpy arrays in favor of inv (~), as this is going to + be deprecated in numpy 1.9 (:issue:`6960`) .. _whatsnew_0140.deprecations: diff --git a/pandas/algos.pyx b/pandas/algos.pyx index 4628853df3953..3b527740505e4 100644 --- a/pandas/algos.pyx +++ b/pandas/algos.pyx @@ -510,7 +510,7 @@ def rank_1d_generic(object in_arr, bint retry=1, ties_method='average', if not retry: raise - valid_locs = (-mask).nonzero()[0] + valid_locs = (~mask).nonzero()[0] ranks.put(valid_locs, rank_1d_generic(values.take(valid_locs), 0, ties_method=ties_method, ascending=ascending)) diff --git a/pandas/computation/ops.py b/pandas/computation/ops.py index 1f57c459149ad..59d3860032cff 100644 --- a/pandas/computation/ops.py +++ b/pandas/computation/ops.py @@ -42,9 +42,7 @@ class Term(StringMixin): def __new__(cls, name, env, side=None, encoding=None): klass = Constant if not isinstance(name, string_types) else cls supr_new = super(Term, klass).__new__ - if PY3: - return supr_new(klass) - return supr_new(klass, name, env, side=side, encoding=encoding) + return supr_new(klass) def __init__(self, name, env, side=None, encoding=None): self._name = name diff --git a/pandas/computation/pytables.py b/pandas/computation/pytables.py index 8fc842d958075..9a1e61ad30386 100644 --- a/pandas/computation/pytables.py +++ b/pandas/computation/pytables.py @@ -33,9 +33,7 @@ class Term(ops.Term): def __new__(cls, name, env, side=None, encoding=None): klass = Constant if not isinstance(name, string_types) else cls supr_new = StringMixin.__new__ - if PY3: - return supr_new(klass) - return supr_new(klass, name, env, side=side, encoding=encoding) + return supr_new(klass) def __init__(self, name, env, side=None, encoding=None): super(Term, self).__init__(name, env, side=side, encoding=encoding) diff --git a/pandas/core/algorithms.py b/pandas/core/algorithms.py index 5efba4a9738af..f0ecce0235b49 100644 --- a/pandas/core/algorithms.py +++ b/pandas/core/algorithms.py @@ -329,7 +329,7 @@ def quantile(x, q, interpolation_method='fraction'): x = np.asarray(x) mask = com.isnull(x) - x = x[-mask] + x = x[~mask] values = np.sort(x) @@ -339,7 +339,7 @@ def _get_score(at): idx = at * (len(values) - 1) if idx % 1 == 0: - score = values[idx] + score = values[int(idx)] else: if interpolation_method == 'fraction': score = _interpolate(values[int(idx)], values[int(idx) + 1], diff --git a/pandas/core/common.py b/pandas/core/common.py index 18a3dba1a44a4..d7a7c1d798731 100644 --- a/pandas/core/common.py +++ b/pandas/core/common.py @@ -248,7 +248,7 @@ def _isnull_ndarraylike_old(obj): # this is the NaT pattern result = values.view('i8') == tslib.iNaT else: - result = -np.isfinite(values) + result = ~np.isfinite(values) # box if isinstance(obj, ABCSeries): @@ -280,12 +280,22 @@ def notnull(obj): res = isnull(obj) if np.isscalar(res): return not res - return -res + return ~res def _is_null_datelike_scalar(other): """ test whether the object is a null datelike, e.g. Nat but guard against passing a non-scalar """ - return (np.isscalar(other) and (isnull(other) or other == tslib.iNaT)) or other is pd.NaT or other is None + if other is pd.NaT or other is None: + return True + elif np.isscalar(other): + + # a timedelta + if hasattr(other,'dtype'): + return other.view('i8') == tslib.iNaT + elif is_integer(other) and other == tslib.iNaT: + return True + return isnull(other) + return False def array_equivalent(left, right): """ @@ -363,7 +373,7 @@ def mask_missing(arr, values_to_mask): values_to_mask = np.array(values_to_mask, dtype=object) na_mask = isnull(values_to_mask) - nonna = values_to_mask[-na_mask] + nonna = values_to_mask[~na_mask] mask = None for x in nonna: diff --git a/pandas/core/format.py b/pandas/core/format.py index 43eb0e890aa62..0a4f65b6bf0e6 100644 --- a/pandas/core/format.py +++ b/pandas/core/format.py @@ -1861,7 +1861,7 @@ def _get_format_timedelta64(values): def impl(x): if x is None or lib.checknull(x): return 'NaT' - elif format_short and x == 0: + elif format_short and com.is_integer(x) and x.view('int64') == 0: return "0 days" if even_days else "00:00:00" else: return lib.repr_timedelta64(x, format=format) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index fcd2e65afddcb..10a0c9050af50 100755 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -3041,7 +3041,7 @@ def update(self, other, join='left', overwrite=True, filter_func=None, this = self[col].values that = other[col].values if filter_func is not None: - mask = -filter_func(this) | isnull(that) + mask = ~filter_func(this) | isnull(that) else: if raise_conflict: mask_this = notnull(that) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 3f2ecd8afd2d4..3aed34c7f188e 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -606,7 +606,11 @@ def _indexed_same(self, other): for a in self._AXIS_ORDERS]) def __neg__(self): - arr = operator.neg(_values_from_object(self)) + values = _values_from_object(self) + if values.dtype == np.bool_: + arr = operator.inv(values) + else: + arr = operator.neg(values) return self._wrap_array(arr, self.axes, copy=False) def __invert__(self): @@ -1459,10 +1463,10 @@ def drop(self, labels, axis=0, level=None, inplace=False, **kwargs): if level is not None: if not isinstance(axis, MultiIndex): raise AssertionError('axis must be a MultiIndex') - indexer = -lib.ismember(axis.get_level_values(level), + indexer = ~lib.ismember(axis.get_level_values(level), set(labels)) else: - indexer = -axis.isin(labels) + indexer = ~axis.isin(labels) slicer = [slice(None)] * self.ndim slicer[self._get_axis_number(axis_name)] = indexer diff --git a/pandas/core/groupby.py b/pandas/core/groupby.py index f650b41ff12be..0a4739f586e40 100644 --- a/pandas/core/groupby.py +++ b/pandas/core/groupby.py @@ -1698,7 +1698,7 @@ def __init__(self, index, grouper=None, obj=None, name=None, level=None, labels = np.empty(len(inds), dtype=inds.dtype) labels[mask] = ok_labels - labels[-mask] = -1 + labels[~mask] = -1 if len(uniques) < len(level_index): level_index = level_index.take(uniques) diff --git a/pandas/core/index.py b/pandas/core/index.py index 8748d0081d2e9..43d0129220a75 100644 --- a/pandas/core/index.py +++ b/pandas/core/index.py @@ -480,10 +480,10 @@ def to_int(): if is_integer(key): return key elif is_float(key): - if not self.is_floating(): - warnings.warn("scalar indexers for index type {0} should be integers and not floating point".format( - type(self).__name__),FutureWarning) - return to_int() + key = to_int() + warnings.warn("scalar indexers for index type {0} should be integers and not floating point".format( + type(self).__name__),FutureWarning) + return key return self._convert_indexer_error(key, 'label') if is_float(key): @@ -498,17 +498,9 @@ def _validate_slicer(self, key, f): """ validate and raise if needed on a slice indexers according to the passed in function """ - if not f(key.start): - self._convert_indexer_error(key.start, 'slice start value') - if not f(key.stop): - self._convert_indexer_error(key.stop, 'slice stop value') - if not f(key.step): - self._convert_indexer_error(key.step, 'slice step value') - - def _convert_slice_indexer_iloc(self, key): - """ convert a slice indexer for iloc only """ - self._validate_slicer(key, lambda v: v is None or is_integer(v)) - return key + for c in ['start','stop','step']: + if not f(getattr(key,c)): + self._convert_indexer_error(key.start, 'slice {0} value'.format(c)) def _convert_slice_indexer_getitem(self, key, is_index_slice=False): """ called from the getitem slicers, determine how to treat the key @@ -520,6 +512,25 @@ def _convert_slice_indexer_getitem(self, key, is_index_slice=False): def _convert_slice_indexer(self, key, typ=None): """ convert a slice indexer. disallow floats in the start/stop/step """ + # validate iloc + if typ == 'iloc': + + # need to coerce to_int if needed + def f(c): + v = getattr(key,c) + if v is None or is_integer(v): + return v + + # warn if its a convertible float + if v == int(v): + warnings.warn("slice indexers when using iloc should be integers " + "and not floating point",FutureWarning) + return int(v) + + self._convert_indexer_error(v, 'slice {0} value'.format(c)) + + return slice(*[ f(c) for c in ['start','stop','step']]) + # validate slicers def validate(v): if v is None or is_integer(v): @@ -530,7 +541,6 @@ def validate(v): return False return True - self._validate_slicer(key, validate) # figure out if this is a positional indexer @@ -543,9 +553,7 @@ def is_int(v): is_index_slice = is_int(start) and is_int(stop) is_positional = is_index_slice and not self.is_integer() - if typ == 'iloc': - return self._convert_slice_indexer_iloc(key) - elif typ == 'getitem': + if typ == 'getitem': return self._convert_slice_indexer_getitem( key, is_index_slice=is_index_slice) @@ -1980,7 +1988,7 @@ def _convert_slice_indexer(self, key, typ=None): """ convert a slice indexer, by definition these are labels unless we are iloc """ if typ == 'iloc': - return self._convert_slice_indexer_iloc(key) + return super(Float64Index, self)._convert_slice_indexer(key, typ=typ) # allow floats here self._validate_slicer( @@ -2386,14 +2394,6 @@ def __unicode__(self): def __len__(self): return len(self.labels[0]) - def _convert_slice_indexer(self, key, typ=None): - """ convert a slice indexer. disallow floats in the start/stop/step """ - - if typ == 'iloc': - return self._convert_slice_indexer_iloc(key) - - return super(MultiIndex, self)._convert_slice_indexer(key, typ=typ) - def _get_names(self): return FrozenList(level.name for level in self.levels) @@ -2997,7 +2997,7 @@ def _drop_from_level(self, labels, level): index = self.levels[i] values = index.get_indexer(labels) - mask = -lib.ismember(self.labels[i], set(values)) + mask = ~lib.ismember(self.labels[i], set(values)) return self[mask] diff --git a/pandas/core/indexing.py b/pandas/core/indexing.py index 459c6abbe334e..63988a5976fc9 100644 --- a/pandas/core/indexing.py +++ b/pandas/core/indexing.py @@ -7,7 +7,7 @@ import pandas.core.common as com from pandas.core.common import (_is_bool_indexer, is_integer_dtype, _asarray_tuplesafe, is_list_like, isnull, - ABCSeries, ABCDataFrame, ABCPanel) + ABCSeries, ABCDataFrame, ABCPanel, is_float) import pandas.lib as lib import numpy as np @@ -1319,6 +1319,7 @@ def _get_slice_axis(self, slice_obj, axis=0): if not _need_slice(slice_obj): return obj + slice_obj = self._convert_slice_indexer(slice_obj, axis) if isinstance(slice_obj, slice): return self._slice(slice_obj, axis=axis, typ='iloc') else: @@ -1363,7 +1364,15 @@ def _getitem_axis(self, key, axis=0, validate_iterable=False): def _convert_to_indexer(self, obj, axis=0, is_setter=False): """ much simpler as we only have to deal with our valid types """ - if self._has_valid_type(obj, axis): + + # make need to convert a float key + if isinstance(obj, slice): + return self._convert_slice_indexer(obj, axis) + + elif is_float(obj): + return self._convert_scalar_indexer(obj, axis) + + elif self._has_valid_type(obj, axis): return obj raise ValueError("Can only index by location with a [%s]" % diff --git a/pandas/core/internals.py b/pandas/core/internals.py index 17c0bf283a8a2..887f7562421d7 100644 --- a/pandas/core/internals.py +++ b/pandas/core/internals.py @@ -1049,7 +1049,7 @@ def to_native_types(self, slicer=None, na_rep='', float_format=None, mask = isnull(values) values[mask] = na_rep if float_format: - imask = (-mask).ravel() + imask = (~mask).ravel() values.flat[imask] = np.array( [float_format % val for val in values.ravel()[imask]]) return values.tolist() @@ -1181,7 +1181,7 @@ def to_native_types(self, slicer=None, na_rep=None, **kwargs): if na_rep is None: na_rep = 'NaT' rvalues[mask] = na_rep - imask = (-mask).ravel() + imask = (~mask).ravel() rvalues.flat[imask] = np.array([lib.repr_timedelta64(val) for val in values.ravel()[imask]], dtype=object) @@ -1531,7 +1531,7 @@ def to_native_types(self, slicer=None, na_rep=None, date_format=None, if na_rep is None: na_rep = 'NaT' rvalues[mask] = na_rep - imask = (-mask).ravel() + imask = (~mask).ravel() if date_format is None: date_formatter = lambda x: Timestamp(x)._repr_base diff --git a/pandas/core/nanops.py b/pandas/core/nanops.py index 9c2df9b5dde9d..43ececae1b737 100644 --- a/pandas/core/nanops.py +++ b/pandas/core/nanops.py @@ -190,9 +190,9 @@ def _isfinite(values): if issubclass(values.dtype.type, (np.timedelta64, np.datetime64)): return isnull(values) elif isinstance(values.dtype, object): - return -np.isfinite(values.astype('float64')) + return ~np.isfinite(values.astype('float64')) - return -np.isfinite(values) + return ~np.isfinite(values) def _na_ok_dtype(dtype): diff --git a/pandas/core/ops.py b/pandas/core/ops.py index b8e92fb25cec5..d4e756371001b 100644 --- a/pandas/core/ops.py +++ b/pandas/core/ops.py @@ -452,7 +452,7 @@ def na_op(x, y): mask = notnull(x) result[mask] = op(x[mask], y) - result, changed = com._maybe_upcast_putmask(result, -mask, pa.NA) + result, changed = com._maybe_upcast_putmask(result, ~mask, pa.NA) result = com._fill_zeros(result, x, y, name, fill_zeros) return result @@ -746,7 +746,7 @@ def na_op(x, y): if np.prod(xrav.shape): result[mask] = op(xrav, y) - result, changed = com._maybe_upcast_putmask(result, -mask, np.nan) + result, changed = com._maybe_upcast_putmask(result, ~mask, np.nan) result = result.reshape(x.shape) result = com._fill_zeros(result, x, y, name, fill_zeros) @@ -817,9 +817,9 @@ def na_op(x, y): result[mask] = op(np.array(list(xrav[mask])), y) if op == operator.ne: # pragma: no cover - np.putmask(result, -mask, True) + np.putmask(result, ~mask, True) else: - np.putmask(result, -mask, False) + np.putmask(result, ~mask, False) result = result.reshape(x.shape) return result @@ -911,7 +911,7 @@ def na_op(x, y): result = pa.empty(len(x), dtype=x.dtype) mask = notnull(x) result[mask] = op(x[mask], y) - result, changed = com._maybe_upcast_putmask(result, -mask, pa.NA) + result, changed = com._maybe_upcast_putmask(result, ~mask, pa.NA) result = com._fill_zeros(result, x, y, name, fill_zeros) return result @@ -947,9 +947,9 @@ def na_op(x, y): result[mask] = op(np.array(list(xrav[mask])), y) if op == operator.ne: # pragma: no cover - np.putmask(result, -mask, True) + np.putmask(result, ~mask, True) else: - np.putmask(result, -mask, False) + np.putmask(result, ~mask, False) result = result.reshape(x.shape) return result diff --git a/pandas/core/series.py b/pandas/core/series.py index 637b2e8bfc67d..c94d7dc9acefd 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -961,7 +961,11 @@ def iteritems(self): # inversion def __neg__(self): - arr = operator.neg(self.values) + values = self.values + if values.dtype == np.bool_: + arr = operator.inv(values) + else: + arr = operator.neg(values) return self._constructor(arr, self.index).__finalize__(self) def __invert__(self): @@ -1646,7 +1650,7 @@ def argsort(self, axis=0, kind='quicksort', order=None): if mask.any(): result = Series( -1, index=self.index, name=self.name, dtype='int64') - notmask = -mask + notmask = ~mask result[notmask] = np.argsort(values[notmask], kind=kind) return self._constructor(result, index=self.index).__finalize__(self) @@ -1767,7 +1771,7 @@ def _try_kind_sort(arr): bad = isnull(arr) - good = -bad + good = ~bad idx = pa.arange(len(self)) argsorted = _try_kind_sort(arr[good]) diff --git a/pandas/core/strings.py b/pandas/core/strings.py index 7bcc534a34a1f..6d40aa175cdb6 100644 --- a/pandas/core/strings.py +++ b/pandas/core/strings.py @@ -51,7 +51,7 @@ def str_cat(arr, others=None, sep=None, na_rep=None): result = np.empty(n, dtype=object) np.putmask(result, na_mask, np.nan) - notmask = -na_mask + notmask = ~na_mask tuples = zip(*[x[notmask] for x in arrays]) cats = [sep.join(tup) for tup in tuples] diff --git a/pandas/sparse/array.py b/pandas/sparse/array.py index 7b23b306d2927..38a5688ed96e8 100644 --- a/pandas/sparse/array.py +++ b/pandas/sparse/array.py @@ -509,7 +509,7 @@ def make_sparse(arr, kind='block', fill_value=nan): length = len(arr) if np.isnan(fill_value): - mask = -np.isnan(arr) + mask = ~np.isnan(arr) else: mask = arr != fill_value diff --git a/pandas/src/inference.pyx b/pandas/src/inference.pyx index eac1e0373f24d..34060d0c57a4e 100644 --- a/pandas/src/inference.pyx +++ b/pandas/src/inference.pyx @@ -152,7 +152,18 @@ def infer_dtype_list(list values): cdef inline bint is_null_datetimelike(v): - return util._checknull(v) or (util.is_integer_object(v) and v == iNaT) or v is NaT + # determine if we have a null for a timedelta/datetime (or integer versions)x + if util._checknull(v): + return True + elif util.is_timedelta64_object(v): + return v.view('int64') == iNaT + elif util.is_datetime64_object(v): + return v.view('int64') == iNaT + elif util.is_integer_object(v): + return v == iNaT + elif v is NaT: + return True + return False cdef inline bint is_datetime(object o): return PyDateTime_Check(o) diff --git a/pandas/tests/test_frame.py b/pandas/tests/test_frame.py index 2aac364d16770..11c065a52d78e 100644 --- a/pandas/tests/test_frame.py +++ b/pandas/tests/test_frame.py @@ -1270,7 +1270,9 @@ def test_getitem_setitem_float_labels(self): df = DataFrame(np.random.randn(5, 5), index=index) # positional slicing only via iloc! - result = df.iloc[1.0:5] + with tm.assert_produces_warning(FutureWarning): + result = df.iloc[1.0:5] + expected = df.reindex([2.5, 3.5, 4.5, 5.0]) assert_frame_equal(result, expected) self.assertEqual(len(result), 4) @@ -1280,15 +1282,26 @@ def test_getitem_setitem_float_labels(self): assert_frame_equal(result, expected) self.assertEqual(len(result), 1) + # GH 4892, float indexers in iloc are deprecated + import warnings + warnings.filterwarnings(action='error', category=FutureWarning) + cp = df.copy() - cp.iloc[1.0:5] = 0 - self.assert_((cp.iloc[1.0:5] == 0).values.all()) - self.assert_((cp.iloc[0:1] == df.iloc[0:1]).values.all()) + def f(): + cp.iloc[1.0:5] = 0 + self.assertRaises(FutureWarning, f) + def f(): + result = cp.iloc[1.0:5] == 0 + self.assertRaises(FutureWarning, f) + self.assertTrue(result.values.all()) + self.assertTrue((cp.iloc[0:1] == df.iloc[0:1]).values.all()) + + warnings.filterwarnings(action='ignore', category=FutureWarning) cp = df.copy() cp.iloc[4:5] = 0 - self.assert_((cp.iloc[4:5] == 0).values.all()) - self.assert_((cp.iloc[0:4] == df.iloc[0:4]).values.all()) + self.assertTrue((cp.iloc[4:5] == 0).values.all()) + self.assertTrue((cp.iloc[0:4] == df.iloc[0:4]).values.all()) # float slicing result = df.ix[1.0:5] @@ -1313,7 +1326,8 @@ def test_getitem_setitem_float_labels(self): cp = df.copy() cp.ix[1.0:5.0] = 0 - self.assert_((cp.ix[1.0:5.0] == 0).values.all()) + result = cp.ix[1.0:5.0] + self.assertTrue((result == 0).values.all()) def test_setitem_single_column_mixed(self): df = DataFrame(randn(5, 3), index=['a', 'b', 'c', 'd', 'e'], @@ -4786,7 +4800,8 @@ def _check_unary_op(op): _check_bin_op(operator.or_) _check_bin_op(operator.xor) - _check_unary_op(operator.neg) + # operator.neg is deprecated in numpy >= 1.9 + _check_unary_op(operator.inv) def test_logical_typeerror(self): if not compat.PY3: @@ -11110,7 +11125,7 @@ def test_rank2(self): exp = DataFrame({"a":[ 3.5, 1. , 3.5, 5. , 6. , 7. , 2. ]}) assert_frame_equal(df.rank(), exp) - + def test_rank_na_option(self): from pandas.compat.scipy import rankdata diff --git a/pandas/tests/test_generic.py b/pandas/tests/test_generic.py index 91bca01ab73b5..42bb76930d783 100644 --- a/pandas/tests/test_generic.py +++ b/pandas/tests/test_generic.py @@ -526,7 +526,7 @@ def test_interpolate_index_values(self): expected = s.copy() bad = isnull(expected.values) - good = -bad + good = ~bad expected = Series( np.interp(vals[bad], vals[good], s.values[good]), index=s.index[bad]) diff --git a/pandas/tests/test_indexing.py b/pandas/tests/test_indexing.py index a105b17795398..d89a88138b8fb 100644 --- a/pandas/tests/test_indexing.py +++ b/pandas/tests/test_indexing.py @@ -3229,48 +3229,92 @@ def test_deprecate_float_indexers(self): tm.makeDateIndex, tm.makePeriodIndex ]: i = index(5) + + for s in [ Series(np.arange(len(i)),index=i), DataFrame(np.random.randn(len(i),len(i)),index=i,columns=i) ]: + self.assertRaises(FutureWarning, lambda : + s.iloc[3.0]) + + # setting + def f(): + s.iloc[3.0] = 0 + self.assertRaises(FutureWarning, f) + + # fallsback to position selection ,series only s = Series(np.arange(len(i)),index=i) - self.assertRaises(FutureWarning, lambda : - s.iloc[3.0]) + s[3] self.assertRaises(FutureWarning, lambda : s[3.0]) - # this is ok! - s[3] - # ints i = index(5) - s = Series(np.arange(len(i))) - self.assertRaises(FutureWarning, lambda : - s.iloc[3.0]) + for s in [ Series(np.arange(len(i))), DataFrame(np.random.randn(len(i),len(i)),index=i,columns=i) ]: + self.assertRaises(FutureWarning, lambda : + s.iloc[3.0]) - # on some arch's this doesn't provide a warning (and thus raise) - # and some it does - try: - s[3.0] - except: - pass + # on some arch's this doesn't provide a warning (and thus raise) + # and some it does + try: + s[3.0] + except: + pass + + # setting + def f(): + s.iloc[3.0] = 0 + self.assertRaises(FutureWarning, f) # floats: these are all ok! i = np.arange(5.) - s = Series(np.arange(len(i)),index=i) - with tm.assert_produces_warning(False): - s[3.0] - with tm.assert_produces_warning(False): - s[3] + for s in [ Series(np.arange(len(i)),index=i), DataFrame(np.random.randn(len(i),len(i)),index=i,columns=i) ]: + with tm.assert_produces_warning(False): + s[3.0] + + with tm.assert_produces_warning(False): + s[3] + + self.assertRaises(FutureWarning, lambda : + s.iloc[3.0]) + + with tm.assert_produces_warning(False): + s.iloc[3] + + with tm.assert_produces_warning(False): + s.loc[3.0] - with tm.assert_produces_warning(False): - s.iloc[3.0] + with tm.assert_produces_warning(False): + s.loc[3] - with tm.assert_produces_warning(False): - s.iloc[3] + def f(): + s.iloc[3.0] = 0 + self.assertRaises(FutureWarning, f) - with tm.assert_produces_warning(False): - s.loc[3.0] + # slices + for index in [ tm.makeIntIndex, tm.makeFloatIndex, + tm.makeStringIndex, tm.makeUnicodeIndex, + tm.makeDateIndex, tm.makePeriodIndex ]: - with tm.assert_produces_warning(False): - s.loc[3] + index = index(5) + for s in [ Series(range(5),index=index), DataFrame(np.random.randn(5,2),index=index) ]: + + # getitem + self.assertRaises(FutureWarning, lambda : + s.iloc[3.0:4]) + self.assertRaises(FutureWarning, lambda : + s.iloc[3.0:4.0]) + self.assertRaises(FutureWarning, lambda : + s.iloc[3:4.0]) + + # setitem + def f(): + s.iloc[3.0:4] = 0 + self.assertRaises(FutureWarning, f) + def f(): + s.iloc[3:4.0] = 0 + self.assertRaises(FutureWarning, f) + def f(): + s.iloc[3.0:4.0] = 0 + self.assertRaises(FutureWarning, f) warnings.filterwarnings(action='ignore', category=FutureWarning) diff --git a/pandas/tests/test_tseries.py b/pandas/tests/test_tseries.py index 1915136f11e47..0bf3f1bec9706 100644 --- a/pandas/tests/test_tseries.py +++ b/pandas/tests/test_tseries.py @@ -338,7 +338,7 @@ def test_rank(): from pandas.compat.scipy import rankdata def _check(arr): - mask = -np.isfinite(arr) + mask = ~np.isfinite(arr) arr = arr.copy() result = algos.rank_1d_float64(arr) arr[mask] = np.inf diff --git a/pandas/tseries/period.py b/pandas/tseries/period.py index 5fca119c14e83..6d9e32433cd1e 100644 --- a/pandas/tseries/period.py +++ b/pandas/tseries/period.py @@ -1065,7 +1065,7 @@ def _format_native_types(self, na_rep=u('NaT'), **kwargs): mask = isnull(self.values) values[mask] = na_rep - imask = -mask + imask = ~mask values[imask] = np.array([u('%s') % dt for dt in values[imask]]) return values.tolist() diff --git a/pandas/tseries/tests/test_timedeltas.py b/pandas/tseries/tests/test_timedeltas.py index 215e6e62c685e..5585233f4a9a5 100644 --- a/pandas/tseries/tests/test_timedeltas.py +++ b/pandas/tseries/tests/test_timedeltas.py @@ -122,8 +122,8 @@ def conv(v): def test_nat_converters(self): _skip_if_numpy_not_friendly() - self.assertEqual(to_timedelta('nat',box=False), tslib.iNaT) - self.assertEqual(to_timedelta('nan',box=False), tslib.iNaT) + self.assertEqual(to_timedelta('nat',box=False).astype('int64'), tslib.iNaT) + self.assertEqual(to_timedelta('nan',box=False).astype('int64'), tslib.iNaT) def test_to_timedelta(self): _skip_if_numpy_not_friendly() @@ -137,7 +137,7 @@ def conv(v): # empty string result = to_timedelta('',box=False) - self.assertEqual(result, tslib.iNaT) + self.assertEqual(result.astype('int64'), tslib.iNaT) result = to_timedelta(['', '']) self.assert_(isnull(result).all()) @@ -302,10 +302,10 @@ def test_to_timedelta_on_missing_values(self): assert_series_equal(actual, expected) actual = pd.to_timedelta(np.nan) - self.assertEqual(actual, timedelta_NaT) + self.assertEqual(actual.astype('int64'), timedelta_NaT.astype('int64')) actual = pd.to_timedelta(pd.NaT) - self.assertEqual(actual, timedelta_NaT) + self.assertEqual(actual.astype('int64'), timedelta_NaT.astype('int64')) def test_timedelta_ops_with_missing_values(self): _skip_if_numpy_not_friendly() diff --git a/pandas/tseries/tests/test_util.py b/pandas/tseries/tests/test_util.py index b10c4351c8725..df556cdc77d08 100644 --- a/pandas/tseries/tests/test_util.py +++ b/pandas/tseries/tests/test_util.py @@ -24,7 +24,7 @@ def test_daily(self): annual = pivot_annual(ts, 'D') doy = ts.index.dayofyear - doy[(-isleapyear(ts.index.year)) & (doy >= 60)] += 1 + doy[(~isleapyear(ts.index.year)) & (doy >= 60)] += 1 for i in range(1, 367): subset = ts[doy == i] @@ -47,7 +47,7 @@ def test_hourly(self): grouped = ts_hourly.groupby(ts_hourly.index.year) hoy = grouped.apply(lambda x: x.reset_index(drop=True)) hoy = hoy.index.droplevel(0).values - hoy[-isleapyear(ts_hourly.index.year) & (hoy >= 1416)] += 24 + hoy[~isleapyear(ts_hourly.index.year) & (hoy >= 1416)] += 24 hoy += 1 annual = pivot_annual(ts_hourly) diff --git a/pandas/tseries/tools.py b/pandas/tseries/tools.py index 6761b5cbb04b0..d01ad56165880 100644 --- a/pandas/tseries/tools.py +++ b/pandas/tseries/tools.py @@ -334,7 +334,7 @@ def calc(carg): def calc_with_mask(carg,mask): result = np.empty(carg.shape, dtype='M8[ns]') iresult = result.view('i8') - iresult[-mask] = tslib.iNaT + iresult[~mask] = tslib.iNaT result[mask] = calc(carg[mask].astype(np.float64).astype(np.int64)).astype('M8[ns]') return result diff --git a/pandas/tseries/util.py b/pandas/tseries/util.py index 664a42543822d..72b12ea495ba0 100644 --- a/pandas/tseries/util.py +++ b/pandas/tseries/util.py @@ -52,7 +52,7 @@ def pivot_annual(series, freq=None): offset = index.dayofyear - 1 # adjust for leap year - offset[(-isleapyear(year)) & (offset >= 59)] += 1 + offset[(~isleapyear(year)) & (offset >= 59)] += 1 columns = lrange(1, 367) # todo: strings like 1/1, 1/25, etc.? @@ -66,7 +66,7 @@ def pivot_annual(series, freq=None): defaulted = grouped.apply(lambda x: x.reset_index(drop=True)) defaulted.index = defaulted.index.droplevel(0) offset = np.asarray(defaulted.index) - offset[-isleapyear(year) & (offset >= 1416)] += 24 + offset[~isleapyear(year) & (offset >= 1416)] += 24 columns = lrange(1, 8785) else: raise NotImplementedError(freq) diff --git a/pandas/tslib.pyx b/pandas/tslib.pyx index ba6f03fd9bbb0..e76a2d0cb6cf1 100644 --- a/pandas/tslib.pyx +++ b/pandas/tslib.pyx @@ -402,17 +402,17 @@ class Timestamp(_Timestamp): if month <= 2: year -= 1 month += 12 - return (day + - np.fix((153*month - 457)/5) + - 365*year + - np.floor(year / 4) - - np.floor(year / 100) + - np.floor(year / 400) + - 1721118.5 + - (self.hour + - self.minute/60.0 + - self.second/3600.0 + - self.microsecond/3600.0/1e+6 + + return (day + + np.fix((153*month - 457)/5) + + 365*year + + np.floor(year / 4) - + np.floor(year / 100) + + np.floor(year / 400) + + 1721118.5 + + (self.hour + + self.minute/60.0 + + self.second/3600.0 + + self.microsecond/3600.0/1e+6 + self.nanosecond/3600.0/1e+9 )/24.0) @@ -1114,7 +1114,7 @@ def array_to_datetime(ndarray[object] values, raise_=False, dayfirst=False, continue raise elif util.is_datetime64_object(val): - if val == np_NaT: + if val is np_NaT or val.view('i8') == iNaT: iresult[i] = iNaT else: try: @@ -1190,7 +1190,11 @@ def array_to_datetime(ndarray[object] values, raise_=False, dayfirst=False, oresult = np.empty(n, dtype=object) for i in range(n): val = values[i] - if util.is_datetime64_object(val): + + # set as nan if is even a datetime NaT + if _checknull_with_nat(val) or val is np_NaT: + oresult[i] = np.nan + elif util.is_datetime64_object(val): oresult[i] = val.item() else: oresult[i] = val diff --git a/pandas/util/testing.py b/pandas/util/testing.py index 8abbb37646b49..95fcc7848c433 100644 --- a/pandas/util/testing.py +++ b/pandas/util/testing.py @@ -54,16 +54,19 @@ K = 4 _RAISE_NETWORK_ERROR_DEFAULT = False +# set testing_mode +testing_mode = os.environ.get('PANDAS_TESTING_MODE','None') +if 'numpy_deprecate' in testing_mode: + warnings.simplefilter('always', DeprecationWarning) + class TestCase(unittest.TestCase): @classmethod def setUpClass(cls): pd.set_option('chained_assignment','raise') - #print("setting up: {0}".format(cls)) @classmethod def tearDownClass(cls): - #print("tearing down up: {0}".format(cls)) pass def assert_numpy_array_equal(self, np_array, assert_equal):