Skip to content

Commit d2d7b4a

Browse files
h-vetinarivictor
authored and
victor
committed
DEPR: list-likes of list-likes in str.cat (pandas-dev#22264)
1 parent 8d23343 commit d2d7b4a

File tree

4 files changed

+45
-19
lines changed

4 files changed

+45
-19
lines changed

doc/source/text.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ The same alignment can be used when ``others`` is a ``DataFrame``:
306306
Concatenating a Series and many objects into a Series
307307
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
308308

309-
All one-dimensional list-likes can be arbitrarily combined in a list-like container (including iterators, ``dict``-views, etc.):
309+
All one-dimensional list-likes can be combined in a list-like container (including iterators, ``dict``-views, etc.):
310310

311311
.. ipython:: python
312312

doc/source/whatsnew/v0.24.0.txt

+4-2
Original file line numberDiff line numberDiff line change
@@ -507,13 +507,15 @@ Other API Changes
507507
Deprecations
508508
~~~~~~~~~~~~
509509

510-
- :meth:`DataFrame.to_stata`, :meth:`read_stata`, :class:`StataReader` and :class:`StataWriter` have deprecated the ``encoding`` argument. The encoding of a Stata dta file is determined by the file type and cannot be changed (:issue:`21244`).
511-
- :meth:`MultiIndex.to_hierarchical` is deprecated and will be removed in a future version (:issue:`21613`)
510+
- :meth:`DataFrame.to_stata`, :meth:`read_stata`, :class:`StataReader` and :class:`StataWriter` have deprecated the ``encoding`` argument. The encoding of a Stata dta file is determined by the file type and cannot be changed (:issue:`21244`)
511+
- :meth:`MultiIndex.to_hierarchical` is deprecated and will be removed in a future version (:issue:`21613`)
512512
- :meth:`Series.ptp` is deprecated. Use ``numpy.ptp`` instead (:issue:`21614`)
513513
- :meth:`Series.compress` is deprecated. Use ``Series[condition]`` instead (:issue:`18262`)
514514
- The signature of :meth:`Series.to_csv` has been uniformed to that of doc:meth:`DataFrame.to_csv`: the name of the first argument is now 'path_or_buf', the order of subsequent arguments has changed, the 'header' argument now defaults to True. (:issue:`19715`)
515515
- :meth:`Categorical.from_codes` has deprecated providing float values for the ``codes`` argument. (:issue:`21767`)
516516
- :func:`pandas.read_table` is deprecated. Instead, use :func:`pandas.read_csv` passing ``sep='\t'`` if necessary (:issue:`21948`)
517+
- :meth:`Series.str.cat` has deprecated using arbitrary list-likes *within* list-likes. A list-like container may still contain
518+
many ``Series``, ``Index`` or 1-dimensional ``np.ndarray``, or alternatively, only scalar values. (:issue:`21950`)
517519

518520
.. _whatsnew_0240.prior_deprecations:
519521

pandas/core/strings.py

+23-8
Original file line numberDiff line numberDiff line change
@@ -1930,8 +1930,8 @@ def _get_series_list(self, others, ignore_index=False):
19301930
19311931
Parameters
19321932
----------
1933-
others : Series, DataFrame, np.ndarray, list-like or list-like of
1934-
objects that are either Series, np.ndarray (1-dim) or list-like
1933+
others : Series, Index, DataFrame, np.ndarray, list-like or list-like
1934+
of objects that are Series, Index or np.ndarray (1-dim)
19351935
ignore_index : boolean, default False
19361936
Determines whether to forcefully align others with index of caller
19371937
@@ -1941,7 +1941,7 @@ def _get_series_list(self, others, ignore_index=False):
19411941
boolean whether FutureWarning should be raised)
19421942
"""
19431943

1944-
# once str.cat defaults to alignment, this function can be simplified;
1944+
# Once str.cat defaults to alignment, this function can be simplified;
19451945
# will not need `ignore_index` and the second boolean output anymore
19461946

19471947
from pandas import Index, Series, DataFrame
@@ -1986,11 +1986,20 @@ def _get_series_list(self, others, ignore_index=False):
19861986
# either one-dimensional list-likes or scalars
19871987
if all(is_list_like(x) for x in others):
19881988
los = []
1989-
warn = False
1989+
join_warn = False
1990+
depr_warn = False
19901991
# iterate through list and append list of series for each
19911992
# element (which we check to be one-dimensional and non-nested)
19921993
while others:
19931994
nxt = others.pop(0) # nxt is guaranteed list-like by above
1995+
1996+
# GH 21950 - DeprecationWarning
1997+
# only allowing Series/Index/np.ndarray[1-dim] will greatly
1998+
# simply this function post-deprecation.
1999+
if not (isinstance(nxt, (Series, Index)) or
2000+
(isinstance(nxt, np.ndarray) and nxt.ndim == 1)):
2001+
depr_warn = True
2002+
19942003
if not isinstance(nxt, (DataFrame, Series,
19952004
Index, np.ndarray)):
19962005
# safety for non-persistent list-likes (e.g. iterators)
@@ -2013,8 +2022,14 @@ def _get_series_list(self, others, ignore_index=False):
20132022
nxt, wnx = self._get_series_list(nxt,
20142023
ignore_index=ignore_index)
20152024
los = los + nxt
2016-
warn = warn or wnx
2017-
return (los, warn)
2025+
join_warn = join_warn or wnx
2026+
2027+
if depr_warn:
2028+
warnings.warn('list-likes other than Series, Index, or '
2029+
'np.ndarray WITHIN another list-like are '
2030+
'deprecated and will be removed in a future '
2031+
'version.', FutureWarning, stacklevel=3)
2032+
return (los, join_warn)
20182033
elif all(not is_list_like(x) for x in others):
20192034
return ([Series(others, index=idx)], False)
20202035
raise TypeError(err_msg)
@@ -2037,8 +2052,8 @@ def cat(self, others=None, sep=None, na_rep=None, join=None):
20372052
Series/Index/DataFrame) if `join` is not None.
20382053
20392054
If others is a list-like that contains a combination of Series,
2040-
np.ndarray (1-dim) or list-like, then all elements will be unpacked
2041-
and must satisfy the above criteria individually.
2055+
Index or np.ndarray (1-dim), then all elements will be unpacked and
2056+
must satisfy the above criteria individually.
20422057
20432058
If others is None, the method returns the concatenation of all
20442059
strings in the calling Series/Index.

pandas/tests/test_strings.py

+17-8
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,9 @@ def test_str_cat_mixed_inputs(self, series_or_index):
313313
assert_series_or_index_equal(s.str.cat([tt, s]), exp)
314314

315315
# Series/Index with list of list-likes
316-
assert_series_or_index_equal(s.str.cat([t.values, list(s)]), exp)
316+
with tm.assert_produces_warning(expected_warning=FutureWarning):
317+
# nested lists will be deprecated
318+
assert_series_or_index_equal(s.str.cat([t.values, list(s)]), exp)
317319

318320
# Series/Index with mixed list of Series/list-like
319321
# s as Series has same index as t -> no warning
@@ -327,7 +329,10 @@ def test_str_cat_mixed_inputs(self, series_or_index):
327329
assert_series_or_index_equal(s.str.cat([tt, s.values]), exp)
328330

329331
# Series/Index with iterator of list-likes
330-
assert_series_or_index_equal(s.str.cat(iter([t.values, list(s)])), exp)
332+
with tm.assert_produces_warning(expected_warning=FutureWarning):
333+
# nested list-likes will be deprecated
334+
assert_series_or_index_equal(s.str.cat(iter([t.values, list(s)])),
335+
exp)
331336

332337
# errors for incorrect lengths
333338
rgx = 'All arrays must be same length, except.*'
@@ -348,11 +353,11 @@ def test_str_cat_mixed_inputs(self, series_or_index):
348353

349354
# list of list-likes
350355
with tm.assert_raises_regex(ValueError, rgx):
351-
s.str.cat([z.values, list(s)])
356+
s.str.cat([z.values, s.values])
352357

353358
# mixed list of Series/list-like
354359
with tm.assert_raises_regex(ValueError, rgx):
355-
s.str.cat([z, list(s)])
360+
s.str.cat([z, s.values])
356361

357362
# errors for incorrect arguments in list-like
358363
rgx = 'others must be Series, Index, DataFrame,.*'
@@ -423,11 +428,15 @@ def test_str_cat_align_mixed_inputs(self, join):
423428
e = concat([t, s], axis=1, join=(join if join == 'inner' else 'outer'))
424429
sa, ea = s.align(e, join=join)
425430
exp = exp_outer.loc[ea.index]
426-
tm.assert_series_equal(s.str.cat([t, u], join=join, na_rep='-'), exp)
431+
432+
with tm.assert_produces_warning(expected_warning=FutureWarning):
433+
# nested lists will be deprecated
434+
tm.assert_series_equal(s.str.cat([t, u], join=join, na_rep='-'),
435+
exp)
427436

428437
# errors for incorrect lengths
429438
rgx = 'If `others` contains arrays or lists.*'
430-
z = ['1', '2', '3']
439+
z = Series(['1', '2', '3']).values
431440

432441
# unindexed object of wrong length
433442
with tm.assert_raises_regex(ValueError, rgx):
@@ -442,8 +451,8 @@ def test_str_cat_special_cases(self):
442451
t = Series(['d', 'a', 'e', 'b'], index=[3, 0, 4, 1])
443452

444453
# iterator of elements with different types
445-
exp = Series(['aaA', 'bbB', 'c-C', 'ddD', '-e-'])
446-
tm.assert_series_equal(s.str.cat(iter([t, ['A', 'B', 'C', 'D']]),
454+
exp = Series(['aaa', 'bbb', 'c-c', 'ddd', '-e-'])
455+
tm.assert_series_equal(s.str.cat(iter([t, s.values]),
447456
join='outer', na_rep='-'), exp)
448457

449458
# right-align with different indexes in others

0 commit comments

Comments
 (0)