Skip to content

CI: Drop numpy 1.6 support #7954

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 1 commit into from
Aug 12, 2014
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ pip install pandas
```

## Dependencies
- [NumPy](http://www.numpy.org): 1.6.1 or higher
- [NumPy](http://www.numpy.org): 1.7.0 or higher
- [python-dateutil](http://labix.org/python-dateutil): 1.5 or higher
- [pytz](http://pytz.sourceforge.net)
- Needed for time zone support with ``pandas.date_range``
Expand Down
2 changes: 1 addition & 1 deletion ci/requirements-2.6.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
numpy==1.6.1
numpy==1.7.0
cython==0.19.1
python-dateutil==1.5
pytz==2013b
Expand Down
2 changes: 1 addition & 1 deletion ci/requirements-2.7_LOCALE.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ xlwt==0.7.5
openpyxl==1.6.2
xlsxwriter==0.4.6
xlrd==0.9.2
numpy==1.6.1
numpy==1.7.1
cython==0.19.1
bottleneck==0.6.0
matplotlib==1.3.0
Expand Down
2 changes: 1 addition & 1 deletion doc/source/install.rst
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ installed), make sure you have `nose
Dependencies
------------

* `NumPy <http://www.numpy.org>`__: 1.6.1 or higher
* `NumPy <http://www.numpy.org>`__: 1.7.0 or higher
* `python-dateutil <http://labix.org/python-dateutil>`__ 1.5
* `pytz <http://pytz.sourceforge.net/>`__
* Needed for time zone support
Expand Down
20 changes: 0 additions & 20 deletions doc/source/timeseries.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1685,23 +1685,3 @@ yields another ``timedelta64[ns]`` dtypes Series.
td * -1
td * Series([1,2,3,4])
Numpy < 1.7 Compatibility
~~~~~~~~~~~~~~~~~~~~~~~~~

Numpy < 1.7 has a broken ``timedelta64`` type that does not correctly work
for arithmetic. pandas bypasses this, but for frequency conversion as above,
you need to create the divisor yourself. The ``np.timetimedelta64`` type only
has 1 argument, the number of **micro** seconds.

The following are equivalent statements in the two versions of numpy.

.. code-block:: python
from distutils.version import LooseVersion
if LooseVersion(np.__version__) <= '1.6.2':
y / np.timedelta(86400*int(1e6))
y / np.timedelta(int(1e6))
else:
y / np.timedelta64(1,'D')
y / np.timedelta64(1,'s')
6 changes: 6 additions & 0 deletions doc/source/v0.15.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ This is a major release from 0.14.1 and includes a small number of API changes,
enhancements, and performance improvements along with a large number of bug fixes. We recommend that all
users upgrade to this version.

.. warning::

pandas >= 0.15.0 will no longer support compatibility with NumPy versions <
1.7.0. If you want to use the latest versions of pandas, please upgrade to
NumPy >= 1.7.0.

- Highlights include:

- The ``Categorical`` type was integrated as a first-class pandas type, see :ref:`here <whatsnew_0150.cat>`
Expand Down
12 changes: 10 additions & 2 deletions pandas/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# pylint: disable-msg=W0614,W0401,W0611,W0622


__docformat__ = 'restructuredtext'

try:
Expand All @@ -18,6 +19,7 @@
from datetime import datetime
import numpy as np


# XXX: HACK for NumPy 1.5.1 to suppress warnings
try:
np.seterr(all='ignore')
Expand All @@ -27,14 +29,20 @@
# numpy versioning
from distutils.version import LooseVersion
_np_version = np.version.short_version
_np_version_under1p6 = LooseVersion(_np_version) < '1.6'
_np_version_under1p7 = LooseVersion(_np_version) < '1.7'
_np_version_under1p8 = LooseVersion(_np_version) < '1.8'
_np_version_under1p9 = LooseVersion(_np_version) < '1.9'


from pandas.version import version as __version__
from pandas.info import __doc__


if LooseVersion(_np_version) < '1.7.0':
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not tested anywhere I assume (as we are not running builds like this), but give a test manually

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tested this

not totally sure how you'd even get past the setup.py but this will raise if somehow you do

raise ImportError('pandas {0} is incompatible with numpy < 1.7.0, '
'your numpy version is {1}. Please upgrade numpy to'
' >= 1.7.0 to use pandas version {0}'.format(__version__,
_np_version))

# let init-time option registration happen
import pandas.core.config_init

Expand Down
7 changes: 6 additions & 1 deletion pandas/core/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,12 @@ def ndim(self):

def item(self):
""" return the first element of the underlying data as a python scalar """
return self.values.item()
try:
return self.values.item()
except IndexError:
# copy numpy's message here because Py26 raises an IndexError
raise ValueError('can only convert an array of size 1 to a '
'Python scalar')

@property
def data(self):
Expand Down
26 changes: 9 additions & 17 deletions pandas/core/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -1848,6 +1848,8 @@ def _possibly_cast_to_datetime(value, dtype, coerce=False):
""" try to cast the array/value to a datetimelike dtype, converting float
nan to iNaT
"""
from pandas.tseries.timedeltas import _possibly_cast_to_timedelta
from pandas.tseries.tools import to_datetime

if dtype is not None:
if isinstance(dtype, compat.string_types):
Expand Down Expand Up @@ -1886,13 +1888,11 @@ def _possibly_cast_to_datetime(value, dtype, coerce=False):
elif np.prod(value.shape) and value.dtype != dtype:
try:
if is_datetime64:
from pandas.tseries.tools import to_datetime
value = to_datetime(value, coerce=coerce).values
elif is_timedelta64:
from pandas.tseries.timedeltas import \
_possibly_cast_to_timedelta
value = _possibly_cast_to_timedelta(value, coerce='compat', dtype=dtype)
except:
value = _possibly_cast_to_timedelta(value,
dtype=dtype)
except (AttributeError, ValueError):
pass

else:
Expand All @@ -1901,28 +1901,20 @@ def _possibly_cast_to_datetime(value, dtype, coerce=False):

# catch a datetime/timedelta that is not of ns variety
# and no coercion specified
if (is_array and value.dtype.kind in ['M','m']):
if is_array and value.dtype.kind in ['M', 'm']:
dtype = value.dtype

if dtype.kind == 'M' and dtype != _NS_DTYPE:
value = value.astype(_NS_DTYPE)

elif dtype.kind == 'm' and dtype != _TD_DTYPE:
from pandas.tseries.timedeltas import \
_possibly_cast_to_timedelta
value = _possibly_cast_to_timedelta(value, coerce='compat')
value = _possibly_cast_to_timedelta(value)

# only do this if we have an array and the dtype of the array is not
# setup already we are not an integer/object, so don't bother with this
# conversion
elif (is_array and not (
issubclass(value.dtype.type, np.integer) or
value.dtype == np.object_)):
pass

# try to infer if we have a datetimelike here
# otherwise pass thru
else:
elif not (is_array and not (issubclass(value.dtype.type, np.integer) or
value.dtype == np.object_)):
value = _possibly_infer_to_datetimelike(value)

return value
Expand Down
17 changes: 1 addition & 16 deletions pandas/core/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from pandas.core.internals import BlockManager
import pandas.core.common as com
import pandas.core.datetools as datetools
from pandas import compat, _np_version_under1p7
from pandas import compat
from pandas.compat import map, zip, lrange, string_types, isidentifier, lmap
from pandas.core.common import (isnull, notnull, is_list_like,
_values_from_object, _maybe_promote,
Expand Down Expand Up @@ -3613,21 +3613,6 @@ def abs(self):
-------
abs: type of caller
"""

# suprimo numpy 1.6 hacking
# for timedeltas
if _np_version_under1p7:

def _convert_timedeltas(x):
if x.dtype.kind == 'm':
return np.abs(x.view('i8')).astype(x.dtype)
return np.abs(x)

if self.ndim == 1:
return _convert_timedeltas(self)
elif self.ndim == 2:
return self.apply(_convert_timedeltas)

return np.abs(self)

_shared_docs['describe'] = """
Expand Down
16 changes: 9 additions & 7 deletions pandas/core/groupby.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
is_timedelta64_dtype, is_datetime64_dtype,
is_categorical_dtype, _values_from_object)
from pandas.core.config import option_context
from pandas import _np_version_under1p7
import pandas.lib as lib
from pandas.lib import Timestamp
import pandas.tslib as tslib
Expand Down Expand Up @@ -2764,18 +2763,21 @@ def _wrap_applied_output(self, keys, values, not_indexed_same=False):

# normally use vstack as its faster than concat
# and if we have mi-columns
if not _np_version_under1p7 or isinstance(v.index,MultiIndex) or key_index is None:
stacked_values = np.vstack([np.asarray(x) for x in values])
result = DataFrame(stacked_values,index=key_index,columns=index)
if isinstance(v.index, MultiIndex) or key_index is None:
stacked_values = np.vstack(map(np.asarray, values))
result = DataFrame(stacked_values, index=key_index,
columns=index)
else:
# GH5788 instead of stacking; concat gets the dtypes correct
from pandas.tools.merge import concat
result = concat(values,keys=key_index,names=key_index.names,
result = concat(values, keys=key_index,
names=key_index.names,
axis=self.axis).unstack()
result.columns = index
else:
stacked_values = np.vstack([np.asarray(x) for x in values])
result = DataFrame(stacked_values.T,index=v.index,columns=key_index)
stacked_values = np.vstack(map(np.asarray, values))
result = DataFrame(stacked_values.T, index=v.index,
columns=key_index)

except (ValueError, AttributeError):
# GH1738: values is list of arrays of unequal lengths fall
Expand Down
6 changes: 2 additions & 4 deletions pandas/core/internals.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
from pandas.util.decorators import cache_readonly

from pandas.tslib import Timestamp
from pandas import compat, _np_version_under1p7
from pandas import compat
from pandas.compat import range, map, zip, u
from pandas.tseries.timedeltas import _coerce_scalar_to_timedelta_type

Expand Down Expand Up @@ -1298,10 +1298,8 @@ def to_native_types(self, slicer=None, na_rep=None, **kwargs):
def get_values(self, dtype=None):
# return object dtypes as datetime.timedeltas
if dtype == object:
if _np_version_under1p7:
return self.values.astype('object')
return lib.map_infer(self.values.ravel(),
lambda x: timedelta(microseconds=x.item()/1000)
lambda x: timedelta(microseconds=x.item() / 1000)
).reshape(self.values.shape)
return self.values

Expand Down
14 changes: 3 additions & 11 deletions pandas/core/ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,9 +258,7 @@ def __init__(self, left, right, name):
self.is_datetime_lhs = com.is_datetime64_dtype(left)
self.is_integer_lhs = left.dtype.kind in ['i', 'u']
self.is_datetime_rhs = com.is_datetime64_dtype(rvalues)
self.is_timedelta_rhs = (com.is_timedelta64_dtype(rvalues)
or (not self.is_datetime_rhs
and pd._np_version_under1p7))
self.is_timedelta_rhs = com.is_timedelta64_dtype(rvalues)
self.is_integer_rhs = rvalues.dtype.kind in ('i', 'u')

self._validate()
Expand Down Expand Up @@ -318,7 +316,7 @@ def _convert_to_array(self, values, name=None, other=None):
"""converts values to ndarray"""
from pandas.tseries.timedeltas import _possibly_cast_to_timedelta

coerce = 'compat' if pd._np_version_under1p7 else True
coerce = True
if not is_list_like(values):
values = np.array([values])
inferred_type = lib.infer_dtype(values)
Expand Down Expand Up @@ -648,13 +646,7 @@ def _radd_compat(left, right):
try:
output = radd(left, right)
except TypeError:
cond = (pd._np_version_under1p6 and
left.dtype == np.object_)
if cond: # pragma: no cover
output = np.empty_like(left)
output.flat[:] = [radd(x, right) for x in left.flat]
else:
raise
raise

return output

Expand Down
8 changes: 1 addition & 7 deletions pandas/io/pytables.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

import numpy as np
from pandas import (Series, TimeSeries, DataFrame, Panel, Panel4D, Index,
MultiIndex, Int64Index, Timestamp, _np_version_under1p7)
MultiIndex, Int64Index, Timestamp)
from pandas.sparse.api import SparseSeries, SparseDataFrame, SparsePanel
from pandas.sparse.array import BlockIndex, IntIndex
from pandas.tseries.api import PeriodIndex, DatetimeIndex
Expand Down Expand Up @@ -1721,9 +1721,6 @@ def set_atom(self, block, block_items, existing_col, min_itemsize,
if inferred_type == 'datetime64':
self.set_atom_datetime64(block)
elif dtype == 'timedelta64[ns]':
if _np_version_under1p7:
raise TypeError(
"timdelta64 is not supported under under numpy < 1.7")
self.set_atom_timedelta64(block)
elif inferred_type == 'date':
raise TypeError(
Expand Down Expand Up @@ -2240,9 +2237,6 @@ def read_array(self, key):
if dtype == u('datetime64'):
ret = np.array(ret, dtype='M8[ns]')
elif dtype == u('timedelta64'):
if _np_version_under1p7:
raise TypeError(
"timedelta64 is not supported under under numpy < 1.7")
ret = np.array(ret, dtype='m8[ns]')

if transposed:
Expand Down
2 changes: 0 additions & 2 deletions pandas/io/tests/test_json/test_pandas.py
Original file line number Diff line number Diff line change
Expand Up @@ -601,8 +601,6 @@ def test_url(self):
self.assertEqual(result[c].dtype, 'datetime64[ns]')

def test_timedelta(self):
tm._skip_if_not_numpy17_friendly()

from datetime import timedelta
converter = lambda x: pd.to_timedelta(x,unit='ms')

Expand Down
4 changes: 1 addition & 3 deletions pandas/io/tests/test_pytables.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
assert_frame_equal,
assert_series_equal)
from pandas import concat, Timestamp
from pandas import compat, _np_version_under1p7
from pandas import compat
from pandas.compat import range, lrange, u
from pandas.util.testing import assert_produces_warning

Expand Down Expand Up @@ -2159,8 +2159,6 @@ def setTZ(tz):
setTZ(orig_tz)

def test_append_with_timedelta(self):
tm._skip_if_not_numpy17_friendly()

# GH 3577
# append timedelta

Expand Down
3 changes: 0 additions & 3 deletions pandas/io/tests/test_sql.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@

import pandas.io.sql as sql
import pandas.util.testing as tm
from pandas import _np_version_under1p7


try:
Expand Down Expand Up @@ -509,8 +508,6 @@ def test_date_and_index(self):

def test_timedelta(self):
# see #6921
tm._skip_if_not_numpy17_friendly()

df = to_timedelta(Series(['00:00:01', '00:00:03'], name='foo')).to_frame()
with tm.assert_produces_warning(UserWarning):
df.to_sql('test_timedelta', self.conn)
Expand Down
Loading