diff --git a/ci/deps/azure-macos-36.yaml b/ci/deps/azure-macos-36.yaml index 831b68d0bb4d3d..f393ed84ecf639 100644 --- a/ci/deps/azure-macos-36.yaml +++ b/ci/deps/azure-macos-36.yaml @@ -20,9 +20,9 @@ dependencies: - matplotlib=2.2.3 - nomkl - numexpr - - numpy=1.13.3 + - numpy=1.14 - openpyxl - - pyarrow + - pyarrow>=0.12.0 - pytables - python-dateutil==2.6.1 - pytz diff --git a/ci/deps/azure-windows-36.yaml b/ci/deps/azure-windows-36.yaml index aa3962da9b4f0d..903a4b4a222f1a 100644 --- a/ci/deps/azure-windows-36.yaml +++ b/ci/deps/azure-windows-36.yaml @@ -20,7 +20,7 @@ dependencies: - numexpr - numpy=1.15.* - openpyxl - - pyarrow + - pyarrow>=0.12.0 - pytables - python-dateutil - pytz diff --git a/doc/redirects.csv b/doc/redirects.csv index a2146edde6324e..fb922eb79e3632 100644 --- a/doc/redirects.csv +++ b/doc/redirects.csv @@ -828,7 +828,6 @@ generated/pandas.MultiIndex.sortlevel,../reference/api/pandas.MultiIndex.sortlev generated/pandas.MultiIndex.swaplevel,../reference/api/pandas.MultiIndex.swaplevel generated/pandas.MultiIndex.to_flat_index,../reference/api/pandas.MultiIndex.to_flat_index generated/pandas.MultiIndex.to_frame,../reference/api/pandas.MultiIndex.to_frame -generated/pandas.MultiIndex.to_hierarchical,../reference/api/pandas.MultiIndex.to_hierarchical generated/pandas.notna,../reference/api/pandas.notna generated/pandas.notnull,../reference/api/pandas.notnull generated/pandas.option_context,../reference/api/pandas.option_context diff --git a/doc/source/getting_started/install.rst b/doc/source/getting_started/install.rst index 04df37427e4f58..9f3ab22496ae72 100644 --- a/doc/source/getting_started/install.rst +++ b/doc/source/getting_started/install.rst @@ -258,7 +258,7 @@ matplotlib 2.2.2 Visualization openpyxl 2.4.8 Reading / writing for xlsx files pandas-gbq 0.8.0 Google Big Query access psycopg2 PostgreSQL engine for sqlalchemy -pyarrow 0.9.0 Parquet and feather reading / writing +pyarrow 0.12.0 Parquet and feather reading / writing pymysql 0.7.11 MySQL engine for sqlalchemy pyreadstat SPSS files (.sav) reading pytables 3.4.2 HDF5 reading / writing diff --git a/doc/source/reference/indexing.rst b/doc/source/reference/indexing.rst index 409791c7530a27..448f020cfa56f0 100644 --- a/doc/source/reference/indexing.rst +++ b/doc/source/reference/indexing.rst @@ -305,7 +305,6 @@ MultiIndex components MultiIndex.set_levels MultiIndex.set_codes - MultiIndex.to_hierarchical MultiIndex.to_flat_index MultiIndex.to_frame MultiIndex.is_lexsorted diff --git a/doc/source/whatsnew/v1.0.0.rst b/doc/source/whatsnew/v1.0.0.rst index 691be559b263f3..8ea29d923ed3f6 100644 --- a/doc/source/whatsnew/v1.0.0.rst +++ b/doc/source/whatsnew/v1.0.0.rst @@ -265,62 +265,62 @@ The following methods now also correctly output values for unobserved categories Increased minimum versions for dependencies ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Some minimum supported versions of dependencies were updated (:issue:`29723`). +Some minimum supported versions of dependencies were updated (:issue:`29766`, :issue:`29723`). If installed, we now require: -+-----------------+-----------------+----------+ -| Package | Minimum Version | Required | -+=================+=================+==========+ -| numpy | 1.13.3 | X | -+-----------------+-----------------+----------+ -| pytz | 2015.4 | X | -+-----------------+-----------------+----------+ -| python-dateutil | 2.6.1 | X | -+-----------------+-----------------+----------+ -| bottleneck | 1.2.1 | | -+-----------------+-----------------+----------+ -| numexpr | 2.6.2 | | -+-----------------+-----------------+----------+ -| pytest (dev) | 4.0.2 | | -+-----------------+-----------------+----------+ ++-----------------+-----------------+----------+---------+ +| Package | Minimum Version | Required | Changed | ++=================+=================+==========+=========+ +| numpy | 1.13.3 | X | | ++-----------------+-----------------+----------+---------+ +| pytz | 2015.4 | X | | ++-----------------+-----------------+----------+---------+ +| python-dateutil | 2.6.1 | X | | ++-----------------+-----------------+----------+---------+ +| bottleneck | 1.2.1 | | | ++-----------------+-----------------+----------+---------+ +| numexpr | 2.6.2 | | | ++-----------------+-----------------+----------+---------+ +| pytest (dev) | 4.0.2 | | | ++-----------------+-----------------+----------+---------+ For `optional libraries `_ the general recommendation is to use the latest version. The following table lists the lowest version per library that is currently being tested throughout the development of pandas. Optional libraries below the lowest tested version may still work, but are not considered supported. -+-----------------+-----------------+ -| Package | Minimum Version | -+=================+=================+ -| beautifulsoup4 | 4.6.0 | -+-----------------+-----------------+ -| fastparquet | 0.3.2 | -+-----------------+-----------------+ -| gcsfs | 0.2.2 | -+-----------------+-----------------+ -| lxml | 3.8.0 | -+-----------------+-----------------+ -| matplotlib | 2.2.2 | -+-----------------+-----------------+ -| openpyxl | 2.4.8 | -+-----------------+-----------------+ -| pyarrow | 0.9.0 | -+-----------------+-----------------+ -| pymysql | 0.7.1 | -+-----------------+-----------------+ -| pytables | 3.4.2 | -+-----------------+-----------------+ -| scipy | 0.19.0 | -+-----------------+-----------------+ -| sqlalchemy | 1.1.4 | -+-----------------+-----------------+ -| xarray | 0.8.2 | -+-----------------+-----------------+ -| xlrd | 1.1.0 | -+-----------------+-----------------+ -| xlsxwriter | 0.9.8 | -+-----------------+-----------------+ -| xlwt | 1.2.0 | -+-----------------+-----------------+ ++-----------------+-----------------+---------+ +| Package | Minimum Version | Changed | ++=================+=================+=========+ +| beautifulsoup4 | 4.6.0 | | ++-----------------+-----------------+---------+ +| fastparquet | 0.3.2 | X | ++-----------------+-----------------+---------+ +| gcsfs | 0.2.2 | | ++-----------------+-----------------+---------+ +| lxml | 3.8.0 | | ++-----------------+-----------------+---------+ +| matplotlib | 2.2.2 | | ++-----------------+-----------------+---------+ +| openpyxl | 2.4.8 | | ++-----------------+-----------------+---------+ +| pyarrow | 0.12.0 | X | ++-----------------+-----------------+---------+ +| pymysql | 0.7.1 | | ++-----------------+-----------------+---------+ +| pytables | 3.4.2 | | ++-----------------+-----------------+---------+ +| scipy | 0.19.0 | | ++-----------------+-----------------+---------+ +| sqlalchemy | 1.1.4 | | ++-----------------+-----------------+---------+ +| xarray | 0.8.2 | | ++-----------------+-----------------+---------+ +| xlrd | 1.1.0 | | ++-----------------+-----------------+---------+ +| xlsxwriter | 0.9.8 | | ++-----------------+-----------------+---------+ +| xlwt | 1.2.0 | | ++-----------------+-----------------+---------+ See :ref:`install.dependencies` and :ref:`install.optional_dependencies` for more. @@ -415,6 +415,11 @@ or ``matplotlib.Axes.plot``. See :ref:`plotting.formatters` for more. - :func:`core.internals.blocks.make_block` no longer accepts the "fastpath" keyword(:issue:`19265`) - :meth:`Block.make_block_same_class` no longer accepts the "dtype" keyword(:issue:`19434`) - Removed the previously deprecated :meth:`ExtensionArray._formatting_values`. Use :attr:`ExtensionArray._formatter` instead. (:issue:`23601`) +- Removed the previously deprecated :meth:`MultiIndex.to_hierarchical` (:issue:`21613`) +- Removed the previously deprecated :attr:`MultiIndex.labels`, use :attr:`MultiIndex.codes` instead (:issue:`23752`) +- Removed the previously deprecated "labels" keyword from the :class:`MultiIndex` constructor, use "codes" instead (:issue:`23752`) +- Removed the previously deprecated :meth:`MultiIndex.set_labels`, use :meth:`MultiIndex.set_codes` instead (:issue:`23752`) +- Removed the previously deprecated "labels" keyword from :meth:`MultiIndex.set_codes`, :meth:`MultiIndex.copy`, :meth:`MultiIndex.drop`, use "codes" instead (:issue:`23752`) - Removed support for legacy HDF5 formats (:issue:`29787`) - :func:`read_excel` removed support for "skip_footer" argument, use "skipfooter" instead (:issue:`18836`) - :func:`read_excel` no longer allows an integer value for the parameter ``usecols``, instead pass a list of integers from 0 to ``usecols`` inclusive (:issue:`23635`) diff --git a/pandas/compat/_optional.py b/pandas/compat/_optional.py index bfe31c6a1d7941..0be201daea425a 100644 --- a/pandas/compat/_optional.py +++ b/pandas/compat/_optional.py @@ -16,7 +16,7 @@ "odfpy": "1.3.0", "openpyxl": "2.4.8", "pandas_gbq": "0.8.0", - "pyarrow": "0.9.0", + "pyarrow": "0.12.0", "pytables": "3.4.2", "pytest": "5.0.1", "s3fs": "0.3.0", diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index dd38bd0ee5f70e..abc3618ef472d9 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -160,6 +160,12 @@ def _new_Index(cls, d): from pandas.core.indexes.period import _new_PeriodIndex return _new_PeriodIndex(cls, **d) + + if issubclass(cls, ABCMultiIndex): + if "labels" in d and "codes" not in d: + # GH#23752 "labels" kwarg has been replaced with "codes" + d["codes"] = d.pop("labels") + return cls.__new__(cls, **d) diff --git a/pandas/core/indexes/multi.py b/pandas/core/indexes/multi.py index 86398613798be1..048112cbf0836b 100644 --- a/pandas/core/indexes/multi.py +++ b/pandas/core/indexes/multi.py @@ -11,7 +11,7 @@ from pandas._libs.hashtable import duplicated_int64 from pandas.compat.numpy import function as nv from pandas.errors import PerformanceWarning, UnsortedIndexError -from pandas.util._decorators import Appender, cache_readonly, deprecate_kwarg +from pandas.util._decorators import Appender, cache_readonly from pandas.core.dtypes.common import ( ensure_int64, @@ -229,9 +229,7 @@ class MultiIndex(Index): of the mentioned helper methods. """ - _deprecations = Index._deprecations | frozenset( - ["labels", "set_labels", "to_hierarchical"] - ) + _deprecations = Index._deprecations | frozenset() # initialize to zero-length tuples to make everything work _typ = "multiindex" @@ -244,7 +242,6 @@ class MultiIndex(Index): # -------------------------------------------------------------------- # Constructors - @deprecate_kwarg(old_arg_name="labels", new_arg_name="codes") def __new__( cls, levels=None, @@ -813,15 +810,6 @@ def set_levels(self, levels, level=None, inplace=False, verify_integrity=True): def codes(self): return self._codes - @property - def labels(self): - warnings.warn( - (".labels was deprecated in version 0.24.0. Use .codes instead."), - FutureWarning, - stacklevel=2, - ) - return self.codes - def _set_codes( self, codes, level=None, copy=False, validate=True, verify_integrity=False ): @@ -854,23 +842,6 @@ def _set_codes( self._tuples = None self._reset_cache() - def set_labels(self, labels, level=None, inplace=False, verify_integrity=True): - warnings.warn( - ( - ".set_labels was deprecated in version 0.24.0. " - "Use .set_codes instead." - ), - FutureWarning, - stacklevel=2, - ) - return self.set_codes( - codes=labels, - level=level, - inplace=inplace, - verify_integrity=verify_integrity, - ) - - @deprecate_kwarg(old_arg_name="labels", new_arg_name="codes") def set_codes(self, codes, level=None, inplace=False, verify_integrity=True): """ Set new codes on MultiIndex. Defaults to returning @@ -947,7 +918,6 @@ def set_codes(self, codes, level=None, inplace=False, verify_integrity=True): if not inplace: return idx - @deprecate_kwarg(old_arg_name="labels", new_arg_name="codes") def copy( self, names=None, @@ -981,7 +951,8 @@ def copy( """ name = kwargs.get("name") names = self._validate_names(name=name, names=names, deep=deep) - + if "labels" in kwargs: + raise TypeError("'labels' argument has been removed; use 'codes' instead") if deep: from copy import deepcopy @@ -1700,62 +1671,6 @@ def to_frame(self, index=True, name=None): result.index = self return result - def to_hierarchical(self, n_repeat, n_shuffle=1): - """ - Return a MultiIndex reshaped to conform to the - shapes given by n_repeat and n_shuffle. - - .. deprecated:: 0.24.0 - - Useful to replicate and rearrange a MultiIndex for combination - with another Index with n_repeat items. - - Parameters - ---------- - n_repeat : int - Number of times to repeat the labels on self. - n_shuffle : int - Controls the reordering of the labels. If the result is going - to be an inner level in a MultiIndex, n_shuffle will need to be - greater than one. The size of each label must divisible by - n_shuffle. - - Returns - ------- - MultiIndex - - Examples - -------- - >>> idx = pd.MultiIndex.from_tuples([(1, 'one'), (1, 'two'), - (2, 'one'), (2, 'two')]) - >>> idx.to_hierarchical(3) - MultiIndex([(1, 'one'), - (1, 'one'), - (1, 'one'), - (1, 'two'), - (1, 'two'), - (1, 'two'), - (2, 'one'), - (2, 'one'), - (2, 'one'), - (2, 'two'), - (2, 'two'), - (2, 'two')], - ) - """ - levels = self.levels - codes = [np.repeat(level_codes, n_repeat) for level_codes in self.codes] - # Assumes that each level_codes is divisible by n_shuffle - codes = [x.reshape(n_shuffle, -1).ravel(order="F") for x in codes] - names = self.names - warnings.warn( - "Method .to_hierarchical is deprecated and will " - "be removed in a future version", - FutureWarning, - stacklevel=2, - ) - return MultiIndex(levels=levels, codes=codes, names=names) - def to_flat_index(self): """ Convert a MultiIndex to an Index of Tuples containing the level values. @@ -2148,7 +2063,6 @@ def repeat(self, repeats, axis=None): def where(self, cond, other=None): raise NotImplementedError(".where is not supported for MultiIndex operations") - @deprecate_kwarg(old_arg_name="labels", new_arg_name="codes") def drop(self, codes, level=None, errors="raise"): """ Make new MultiIndex with passed list of codes deleted diff --git a/pandas/io/feather_format.py b/pandas/io/feather_format.py index dffe04fb637205..01118d7b7cd3e9 100644 --- a/pandas/io/feather_format.py +++ b/pandas/io/feather_format.py @@ -1,7 +1,5 @@ """ feather-format compat """ -from distutils.version import LooseVersion - from pandas.compat._optional import import_optional_dependency from pandas import DataFrame, Int64Index, RangeIndex @@ -96,15 +94,9 @@ def read_feather(path, columns=None, use_threads=True): ------- type of object stored in file """ - pyarrow = import_optional_dependency("pyarrow") + import_optional_dependency("pyarrow") from pyarrow import feather path = _stringify_path(path) - if LooseVersion(pyarrow.__version__) < LooseVersion("0.11.0"): - int_use_threads = int(use_threads) - if int_use_threads < 1: - int_use_threads = 1 - return feather.read_feather(path, columns=columns, nthreads=int_use_threads) - return feather.read_feather(path, columns=columns, use_threads=bool(use_threads)) diff --git a/pandas/tests/extension/arrow/test_bool.py b/pandas/tests/extension/arrow/test_bool.py index 9c53210b75d6b2..e88c63b19003f8 100644 --- a/pandas/tests/extension/arrow/test_bool.py +++ b/pandas/tests/extension/arrow/test_bool.py @@ -5,7 +5,7 @@ from pandas.tests.extension import base import pandas.util.testing as tm -pytest.importorskip("pyarrow", minversion="0.10.0") +pytest.importorskip("pyarrow", minversion="0.12.0") from .arrays import ArrowBoolArray, ArrowBoolDtype # isort:skip diff --git a/pandas/tests/extension/arrow/test_string.py b/pandas/tests/extension/arrow/test_string.py index 06f149aa4b75fd..baedcf0dd90882 100644 --- a/pandas/tests/extension/arrow/test_string.py +++ b/pandas/tests/extension/arrow/test_string.py @@ -2,7 +2,7 @@ import pandas as pd -pytest.importorskip("pyarrow", minversion="0.10.0") +pytest.importorskip("pyarrow", minversion="0.12.0") from .arrays import ArrowStringDtype # isort:skip diff --git a/pandas/tests/indexes/multi/test_constructor.py b/pandas/tests/indexes/multi/test_constructor.py index d2c95b12d53397..c0ec889d170d6c 100644 --- a/pandas/tests/indexes/multi/test_constructor.py +++ b/pandas/tests/indexes/multi/test_constructor.py @@ -128,18 +128,6 @@ def test_na_levels(): tm.assert_index_equal(result, expected) -def test_labels_deprecated(idx): - # GH23752 - with tm.assert_produces_warning(FutureWarning): - MultiIndex( - levels=[["foo", "bar", "baz", "qux"]], - labels=[[0, 1, 2, 3]], - names=["first"], - ) - with tm.assert_produces_warning(FutureWarning): - idx.labels - - def test_copy_in_constructor(): levels = np.array(["a", "b", "c"]) codes = np.array([1, 1, 2, 0, 0, 1, 1]) diff --git a/pandas/tests/indexes/multi/test_conversion.py b/pandas/tests/indexes/multi/test_conversion.py index 3fc73dd05bc726..a0b17ae8924b7e 100644 --- a/pandas/tests/indexes/multi/test_conversion.py +++ b/pandas/tests/indexes/multi/test_conversion.py @@ -133,59 +133,8 @@ def test_to_frame_resulting_column_order(): assert result == expected -def test_to_hierarchical(): - index = MultiIndex.from_tuples([(1, "one"), (1, "two"), (2, "one"), (2, "two")]) - with tm.assert_produces_warning(FutureWarning, check_stacklevel=False): - result = index.to_hierarchical(3) - expected = MultiIndex( - levels=[[1, 2], ["one", "two"]], - codes=[ - [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1], - [0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1], - ], - ) - tm.assert_index_equal(result, expected) - assert result.names == index.names - - # K > 1 - with tm.assert_produces_warning(FutureWarning, check_stacklevel=False): - result = index.to_hierarchical(3, 2) - expected = MultiIndex( - levels=[[1, 2], ["one", "two"]], - codes=[ - [0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1], - [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1], - ], - ) - tm.assert_index_equal(result, expected) - assert result.names == index.names - - # non-sorted - index = MultiIndex.from_tuples( - [(2, "c"), (1, "b"), (2, "a"), (2, "b")], names=["N1", "N2"] - ) - - with tm.assert_produces_warning(FutureWarning, check_stacklevel=False): - result = index.to_hierarchical(2) - expected = MultiIndex.from_tuples( - [ - (2, "c"), - (2, "c"), - (1, "b"), - (1, "b"), - (2, "a"), - (2, "a"), - (2, "b"), - (2, "b"), - ], - names=["N1", "N2"], - ) - tm.assert_index_equal(result, expected) - assert result.names == index.names - - def test_roundtrip_pickle_with_tz(): - return + return # FIXME: this can't be right? # GH 8367 # round-trip of timezone @@ -198,7 +147,7 @@ def test_roundtrip_pickle_with_tz(): def test_pickle(indices): - return + return # FIXME: this can't be right? unpickled = tm.round_trip_pickle(indices) assert indices.equals(unpickled) diff --git a/pandas/tests/indexes/multi/test_copy.py b/pandas/tests/indexes/multi/test_copy.py index 2668197535fcc3..12cd0db6936f55 100644 --- a/pandas/tests/indexes/multi/test_copy.py +++ b/pandas/tests/indexes/multi/test_copy.py @@ -35,12 +35,6 @@ def test_shallow_copy(idx): assert_multiindex_copied(i_copy, idx) -def test_labels_deprecated(idx): - # GH23752 - with tm.assert_produces_warning(FutureWarning): - idx.copy(labels=idx.codes) - - def test_view(idx): i_view = idx.view() assert_multiindex_copied(i_view, idx) diff --git a/pandas/tests/indexes/multi/test_get_set.py b/pandas/tests/indexes/multi/test_get_set.py index 5ab817d8468c3a..ec3c654ecb1eda 100644 --- a/pandas/tests/indexes/multi/test_get_set.py +++ b/pandas/tests/indexes/multi/test_get_set.py @@ -306,27 +306,6 @@ def test_set_codes(idx): result.set_codes(codes=new_codes, level=1, inplace=True) assert result.equals(expected) - with tm.assert_produces_warning(FutureWarning): - ind.set_codes(labels=new_codes, level=1) - - -def test_set_labels_deprecated(): - # GH23752 - ind = pd.MultiIndex.from_tuples([(0, i) for i in range(130)]) - new_labels = range(129, -1, -1) - expected = pd.MultiIndex.from_tuples([(0, i) for i in new_labels]) - - # [w/o mutation] - with tm.assert_produces_warning(FutureWarning): - result = ind.set_labels(labels=new_labels, level=1) - assert result.equals(expected) - - # [w/ mutation] - result = ind.copy() - with tm.assert_produces_warning(FutureWarning): - result.set_labels(labels=new_labels, level=1, inplace=True) - assert result.equals(expected) - def test_set_levels_codes_names_bad_input(idx): levels, codes = idx.levels, idx.codes