DEPR: list-likes of list-likes in str.cat by h-vetinari · Pull Request #22264 · pandas-dev/pandas (original) (raw)
As mentioned in #21950, my suggestion is to modify the allowed combinations (as of v0.23) as follows:
Type of "others" | action | comment
---------------------------------------------------------------------
list-like of strings | keep | as before; mimics behavior elsewhere,
cf.: pd.Series(range(3)) + [2,4,6]
Series | keep |
np.ndarray (1-dim) | keep |
DataFrame | keep | sequential concatenation
np.ndarray (2-dim) | keep | sequential concatenation
list-like of
Series/Index/np.ndarray (1-dim) | keep | sequential concatenation
list-like containing list-likes (1-dim)
other than Series/Index/np.ndarray | DEPR | sequential concatenation
In other words, if the user wants sequential concatenation, there are many possibilities available, and list-of-lists does not have to be one of them, IMO. This would substantially simplify (post-deprecation) the code for str.cat._get_series_list
:
def _get_series_list(self, others):
"""
Auxiliary function for :meth:`str.cat`. Turn potentially mixed input
into a list of Series (elements without an index must match the length
of the calling Series/Index).
Parameters
----------
others : Series, DataFrame, np.ndarray, list-like or list-like of
objects that are either Series, Index or np.ndarray (1-dim)
Returns
-------
list : others transformed into list of Series
"""
from pandas import Index, Series, DataFrame
# self._orig is either Series or Index
idx = self._orig if isinstance(self._orig, Index) else self._orig.index
# Generally speaking, all objects without an index inherit the index
# `idx` of the calling Series/Index - i.e. must have matching length.
# Objects with an index (i.e. Series/Index/DataFrame) keep their own.
if isinstance(others, Series):
return [others]
elif isinstance(others, Index):
return [Series(others.values, index=others)]
elif isinstance(others, DataFrame):
return [others[x] for x in others]
elif isinstance(others, np.ndarray) and others.ndim == 2:
others = DataFrame(others, index=idx)
return [others[x] for x in others]
elif is_list_like(others):
others = list(others) # ensure iterators do not get read twice etc
# in case of list-like `others`, all elements must be
# either Series/Index/np.ndarray (1-dim)...
if all(isinstance(x, (Series, Index))
or (isinstance(x, np.ndarray) and x.ndim == 1) for x in others):
los = []
while others: # iterate through list and append each element
los = los + self._get_series_list(others.pop(0))
return los
# ... or just strings
elif all(not is_list_like(x) for x in others):
return [Series(others, index=idx)]
raise TypeError('others must be Series, Index, DataFrame, np.ndarrary or '
'list-like (either containing only strings or containing '
'only objects of type Series/Index/np.ndarray[1-dim])')