From e632b454dc824cc0cdfca36b11bd66963ccb2b62 Mon Sep 17 00:00:00 2001 From: Joris Van den Bossche Date: Fri, 10 Nov 2017 16:01:39 +0100 Subject: [PATCH 1/5] DEPR: deprecate (Sparse)Series.from_array --- doc/source/whatsnew/v0.22.0.txt | 2 +- pandas/core/frame.py | 14 ++++++-------- pandas/core/series.py | 8 ++++++++ pandas/core/sparse/series.py | 6 +++++- pandas/tests/series/test_api.py | 5 +++++ pandas/tests/series/test_timeseries.py | 5 +++-- 6 files changed, 28 insertions(+), 12 deletions(-) diff --git a/doc/source/whatsnew/v0.22.0.txt b/doc/source/whatsnew/v0.22.0.txt index 943b6bb84fb47..f06a507c6318c 100644 --- a/doc/source/whatsnew/v0.22.0.txt +++ b/doc/source/whatsnew/v0.22.0.txt @@ -51,7 +51,7 @@ Other API Changes Deprecations ~~~~~~~~~~~~ -- +- ``Series.from_array`` and ``SparseSeries.from_array`` are deprecated. Use the normal constructor ``Series(..)`` and ``SparseSeries(..)`` instead (:issue:`18213`). - - diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 70f1ff0a5380d..e7b7f9cfcab81 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -2099,10 +2099,8 @@ def _ixs(self, i, axis=0): if index_len and not len(values): values = np.array([np.nan] * index_len, dtype=object) - result = self._constructor_sliced.from_array(values, - index=self.index, - name=label, - fastpath=True) + result = self._constructor_sliced(values, index=self.index, + name=label, fastpath=True) # this is a cached value, mark it so result._set_as_cached(label, self) @@ -2496,8 +2494,8 @@ def _box_item_values(self, key, values): def _box_col_values(self, values, items): """ provide boxed values for a column """ - return self._constructor_sliced.from_array(values, index=self.index, - name=items, fastpath=True) + return self._constructor_sliced(values, index=self.index, + name=items, fastpath=True) def __setitem__(self, key, value): key = com._apply_if_callable(key, self) @@ -4915,8 +4913,8 @@ def _apply_standard(self, func, axis, ignore_failures=False, reduce=True): res_index = self.index res_columns = self.columns values = self.values - series_gen = (Series.from_array(arr, index=res_columns, name=name, - dtype=dtype) + series_gen = (Series(arr, index=res_columns, name=name, + dtype=dtype) for i, (arr, name) in enumerate(zip(values, res_index))) else: # pragma : no cover diff --git a/pandas/core/series.py b/pandas/core/series.py index 1c92c4b8850ee..bba46eee22116 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -273,6 +273,14 @@ def __init__(self, data=None, index=None, dtype=None, name=None, @classmethod def from_array(cls, arr, index=None, name=None, dtype=None, copy=False, fastpath=False): + """ + DEPRECATED: use the pd.Series(..) constructor instead. + + """ + warnings.warn("'from_array' is deprecated and will be removed in a " + "future version. Please use the pd.Series(..) " + "constructor instead.", FutureWarning, stacklevel=2) + # return a sparse series here if isinstance(arr, ABCSparseArray): from pandas.core.sparse.series import SparseSeries diff --git a/pandas/core/sparse/series.py b/pandas/core/sparse/series.py index 17d0737ba7c63..6814d837279a1 100644 --- a/pandas/core/sparse/series.py +++ b/pandas/core/sparse/series.py @@ -256,8 +256,12 @@ def npoints(self): def from_array(cls, arr, index=None, name=None, copy=False, fill_value=None, fastpath=False): """ - Simplified alternate constructor + DEPRECATED: use the pd.SparseSeries(..) constructor instead. + """ + warnings.warn("'from_array' is deprecated and will be removed in a " + "future version. Please use the pd.SparseSeries(..) " + "constructor instead.", FutureWarning, stacklevel=2) return cls(arr, index=index, name=name, copy=copy, fill_value=fill_value, fastpath=fastpath) diff --git a/pandas/tests/series/test_api.py b/pandas/tests/series/test_api.py index c1e4189283928..9aae40e1b8dbb 100644 --- a/pandas/tests/series/test_api.py +++ b/pandas/tests/series/test_api.py @@ -195,6 +195,11 @@ def test_constructor_dict_timedelta_index(self): ) self._assert_series_equal(result, expected) + def test_from_array_deprecated(self): + + with tm.assert_produces_warning(FutureWarning): + self.series_klass.from_array([1, 2, 3]) + class TestSeriesMisc(TestData, SharedWithSparse): diff --git a/pandas/tests/series/test_timeseries.py b/pandas/tests/series/test_timeseries.py index 6018260708335..89029a35d73de 100644 --- a/pandas/tests/series/test_timeseries.py +++ b/pandas/tests/series/test_timeseries.py @@ -919,8 +919,9 @@ def test_from_M8_structured(self): assert isinstance(s[0], Timestamp) assert s[0] == dates[0][0] - s = Series.from_array(arr['Date'], Index([0])) - assert s[0] == dates[0][0] + with pytest.warns(FutureWarning): + s = Series.from_array(arr['Date'], Index([0])) + assert s[0] == dates[0][0] def test_get_level_values_box(self): from pandas import MultiIndex From 927d47c51a805ddd1428c00651014d6d8613e211 Mon Sep 17 00:00:00 2001 From: Joris Van den Bossche Date: Mon, 13 Nov 2017 11:50:35 +0100 Subject: [PATCH 2/5] keep as private method for internal use --- pandas/core/frame.py | 12 ++++++------ pandas/core/series.py | 11 +++++++++++ pandas/core/sparse/series.py | 6 ++++++ 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index e7b7f9cfcab81..091da7ae4b43f 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -2099,8 +2099,8 @@ def _ixs(self, i, axis=0): if index_len and not len(values): values = np.array([np.nan] * index_len, dtype=object) - result = self._constructor_sliced(values, index=self.index, - name=label, fastpath=True) + result = self._constructor_sliced._from_array( + values, index=self.index, name=label, fastpath=True) # this is a cached value, mark it so result._set_as_cached(label, self) @@ -2494,8 +2494,8 @@ def _box_item_values(self, key, values): def _box_col_values(self, values, items): """ provide boxed values for a column """ - return self._constructor_sliced(values, index=self.index, - name=items, fastpath=True) + return self._constructor_sliced._from_array(values, index=self.index, + name=items, fastpath=True) def __setitem__(self, key, value): key = com._apply_if_callable(key, self) @@ -4913,8 +4913,8 @@ def _apply_standard(self, func, axis, ignore_failures=False, reduce=True): res_index = self.index res_columns = self.columns values = self.values - series_gen = (Series(arr, index=res_columns, name=name, - dtype=dtype) + series_gen = (Series._from_array(arr, index=res_columns, name=name, + dtype=dtype) for i, (arr, name) in enumerate(zip(values, res_index))) else: # pragma : no cover diff --git a/pandas/core/series.py b/pandas/core/series.py index bba46eee22116..7c988ca64fed3 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -280,7 +280,18 @@ def from_array(cls, arr, index=None, name=None, dtype=None, copy=False, warnings.warn("'from_array' is deprecated and will be removed in a " "future version. Please use the pd.Series(..) " "constructor instead.", FutureWarning, stacklevel=2) + cls.from_array(arr, index=index, name=name, dtype=dtype, copy=copy, + fastpath=fastpath) + @classmethod + def _from_array(cls, arr, index=None, name=None, dtype=None, copy=False, + fastpath=False): + """ + Internal method used in DataFrame.__setitem__/__getitem__. + Difference with Series(..) is that this method checks if a sparse + array is passed. + + """ # return a sparse series here if isinstance(arr, ABCSparseArray): from pandas.core.sparse.series import SparseSeries diff --git a/pandas/core/sparse/series.py b/pandas/core/sparse/series.py index 6814d837279a1..b5ce3efe9f85d 100644 --- a/pandas/core/sparse/series.py +++ b/pandas/core/sparse/series.py @@ -262,6 +262,12 @@ def from_array(cls, arr, index=None, name=None, copy=False, warnings.warn("'from_array' is deprecated and will be removed in a " "future version. Please use the pd.SparseSeries(..) " "constructor instead.", FutureWarning, stacklevel=2) + return cls._from_array(arr, index=index, name=name, copy=copy, + fill_value=fill_value, fastpath=fastpath) + + @classmethod + def _from_array(cls, arr, index=None, name=None, copy=False, + fill_value=None, fastpath=False): return cls(arr, index=index, name=name, copy=copy, fill_value=fill_value, fastpath=fastpath) From a447b3cbcee491b54a2f76788ea0629139ee4b07 Mon Sep 17 00:00:00 2001 From: Joris Van den Bossche Date: Mon, 13 Nov 2017 13:01:44 +0100 Subject: [PATCH 3/5] fixup --- pandas/core/series.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/series.py b/pandas/core/series.py index 7c988ca64fed3..37928d2fd4420 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -280,7 +280,7 @@ def from_array(cls, arr, index=None, name=None, dtype=None, copy=False, warnings.warn("'from_array' is deprecated and will be removed in a " "future version. Please use the pd.Series(..) " "constructor instead.", FutureWarning, stacklevel=2) - cls.from_array(arr, index=index, name=name, dtype=dtype, copy=copy, + cls._from_array(arr, index=index, name=name, dtype=dtype, copy=copy, fastpath=fastpath) @classmethod From 521dad333b9325d1b1bd6422172c154c31d10e2b Mon Sep 17 00:00:00 2001 From: Joris Van den Bossche Date: Mon, 13 Nov 2017 19:03:14 +0100 Subject: [PATCH 4/5] fixup --- pandas/core/series.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas/core/series.py b/pandas/core/series.py index 37928d2fd4420..a14b77015fc98 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -280,8 +280,8 @@ def from_array(cls, arr, index=None, name=None, dtype=None, copy=False, warnings.warn("'from_array' is deprecated and will be removed in a " "future version. Please use the pd.Series(..) " "constructor instead.", FutureWarning, stacklevel=2) - cls._from_array(arr, index=index, name=name, dtype=dtype, copy=copy, - fastpath=fastpath) + return cls._from_array(arr, index=index, name=name, dtype=dtype, copy=copy, + fastpath=fastpath) @classmethod def _from_array(cls, arr, index=None, name=None, dtype=None, copy=False, From 4317073cdf12ea882955ca0ed369cf04454c47f2 Mon Sep 17 00:00:00 2001 From: Joris Van den Bossche Date: Tue, 14 Nov 2017 21:35:20 +0100 Subject: [PATCH 5/5] pep8 --- pandas/core/series.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas/core/series.py b/pandas/core/series.py index a14b77015fc98..0b41fe55dd70f 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -280,8 +280,8 @@ def from_array(cls, arr, index=None, name=None, dtype=None, copy=False, warnings.warn("'from_array' is deprecated and will be removed in a " "future version. Please use the pd.Series(..) " "constructor instead.", FutureWarning, stacklevel=2) - return cls._from_array(arr, index=index, name=name, dtype=dtype, copy=copy, - fastpath=fastpath) + return cls._from_array(arr, index=index, name=name, dtype=dtype, + copy=copy, fastpath=fastpath) @classmethod def _from_array(cls, arr, index=None, name=None, dtype=None, copy=False,