Skip to content

Commit 14d0b0f

Browse files
h-vetinariquintusdias
authored andcommitted
DEPR: execute deprecations for str.cat in v1.0 (pandas-dev#27611)
1 parent c7154e7 commit 14d0b0f

File tree

3 files changed

+79
-185
lines changed

3 files changed

+79
-185
lines changed

doc/source/whatsnew/v1.0.0.rst

+2
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ Removal of prior version deprecations/changes
6363
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6464
- Removed the previously deprecated :meth:`Series.get_value`, :meth:`Series.set_value`, :meth:`DataFrame.get_value`, :meth:`DataFrame.set_value` (:issue:`17739`)
6565
- Changed the the default value of `inplace` in :meth:`DataFrame.set_index` and :meth:`Series.set_axis`. It now defaults to False (:issue:`27600`)
66+
- :meth:`pandas.Series.str.cat` now defaults to aligning ``others``, using ``join='left'`` (:issue:`27611`)
67+
- :meth:`pandas.Series.str.cat` does not accept list-likes *within* list-likes anymore (:issue:`27611`)
6668
-
6769

6870
.. _whatsnew_1000.performance:

pandas/core/strings.py

+44-131
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,12 @@
2121
is_scalar,
2222
is_string_like,
2323
)
24-
from pandas.core.dtypes.generic import ABCIndexClass, ABCMultiIndex, ABCSeries
24+
from pandas.core.dtypes.generic import (
25+
ABCDataFrame,
26+
ABCIndexClass,
27+
ABCMultiIndex,
28+
ABCSeries,
29+
)
2530
from pandas.core.dtypes.missing import isna
2631

2732
from pandas.core.algorithms import take_1d
@@ -2061,130 +2066,64 @@ def cons_row(x):
20612066
cons = self._orig._constructor
20622067
return cons(result, name=name, index=index)
20632068

2064-
def _get_series_list(self, others, ignore_index=False):
2069+
def _get_series_list(self, others):
20652070
"""
20662071
Auxiliary function for :meth:`str.cat`. Turn potentially mixed input
20672072
into a list of Series (elements without an index must match the length
20682073
of the calling Series/Index).
20692074
20702075
Parameters
20712076
----------
2072-
others : Series, Index, DataFrame, np.ndarray, list-like or list-like
2073-
of objects that are Series, Index or np.ndarray (1-dim)
2074-
ignore_index : boolean, default False
2075-
Determines whether to forcefully align others with index of caller
2077+
others : Series, DataFrame, np.ndarray, list-like or list-like of
2078+
objects that are either Series, Index or np.ndarray (1-dim)
20762079
20772080
Returns
20782081
-------
2079-
tuple : (others transformed into list of Series,
2080-
boolean whether FutureWarning should be raised)
2082+
list : others transformed into list of Series
20812083
"""
2082-
2083-
# Once str.cat defaults to alignment, this function can be simplified;
2084-
# will not need `ignore_index` and the second boolean output anymore
2085-
20862084
from pandas import Series, DataFrame
20872085

20882086
# self._orig is either Series or Index
20892087
idx = self._orig if isinstance(self._orig, ABCIndexClass) else self._orig.index
20902088

2091-
err_msg = (
2092-
"others must be Series, Index, DataFrame, np.ndarray or "
2093-
"list-like (either containing only strings or containing "
2094-
"only objects of type Series/Index/list-like/np.ndarray)"
2095-
)
2096-
20972089
# Generally speaking, all objects without an index inherit the index
20982090
# `idx` of the calling Series/Index - i.e. must have matching length.
2099-
# Objects with an index (i.e. Series/Index/DataFrame) keep their own
2100-
# index, *unless* ignore_index is set to True.
2091+
# Objects with an index (i.e. Series/Index/DataFrame) keep their own.
21012092
if isinstance(others, ABCSeries):
2102-
warn = not others.index.equals(idx)
2103-
# only reconstruct Series when absolutely necessary
2104-
los = [
2105-
Series(others.values, index=idx) if ignore_index and warn else others
2106-
]
2107-
return (los, warn)
2093+
return [others]
21082094
elif isinstance(others, ABCIndexClass):
2109-
warn = not others.equals(idx)
2110-
los = [Series(others.values, index=(idx if ignore_index else others))]
2111-
return (los, warn)
2112-
elif isinstance(others, DataFrame):
2113-
warn = not others.index.equals(idx)
2114-
if ignore_index and warn:
2115-
# without copy, this could change "others"
2116-
# that was passed to str.cat
2117-
others = others.copy()
2118-
others.index = idx
2119-
return ([others[x] for x in others], warn)
2095+
return [Series(others.values, index=others)]
2096+
elif isinstance(others, ABCDataFrame):
2097+
return [others[x] for x in others]
21202098
elif isinstance(others, np.ndarray) and others.ndim == 2:
21212099
others = DataFrame(others, index=idx)
2122-
return ([others[x] for x in others], False)
2100+
return [others[x] for x in others]
21232101
elif is_list_like(others, allow_sets=False):
21242102
others = list(others) # ensure iterators do not get read twice etc
21252103

21262104
# in case of list-like `others`, all elements must be
2127-
# either one-dimensional list-likes or scalars
2128-
if all(is_list_like(x, allow_sets=False) for x in others):
2105+
# either Series/Index/np.ndarray (1-dim)...
2106+
if all(
2107+
isinstance(x, (ABCSeries, ABCIndexClass))
2108+
or (isinstance(x, np.ndarray) and x.ndim == 1)
2109+
for x in others
2110+
):
21292111
los = []
2130-
join_warn = False
2131-
depr_warn = False
2132-
# iterate through list and append list of series for each
2133-
# element (which we check to be one-dimensional and non-nested)
2134-
while others:
2135-
nxt = others.pop(0) # nxt is guaranteed list-like by above
2136-
2137-
# GH 21950 - DeprecationWarning
2138-
# only allowing Series/Index/np.ndarray[1-dim] will greatly
2139-
# simply this function post-deprecation.
2140-
if not (
2141-
isinstance(nxt, (Series, ABCIndexClass))
2142-
or (isinstance(nxt, np.ndarray) and nxt.ndim == 1)
2143-
):
2144-
depr_warn = True
2145-
2146-
if not isinstance(
2147-
nxt, (DataFrame, Series, ABCIndexClass, np.ndarray)
2148-
):
2149-
# safety for non-persistent list-likes (e.g. iterators)
2150-
# do not map indexed/typed objects; info needed below
2151-
nxt = list(nxt)
2152-
2153-
# known types for which we can avoid deep inspection
2154-
no_deep = (
2155-
isinstance(nxt, np.ndarray) and nxt.ndim == 1
2156-
) or isinstance(nxt, (Series, ABCIndexClass))
2157-
# nested list-likes are forbidden:
2158-
# -> elements of nxt must not be list-like
2159-
is_legal = (no_deep and nxt.dtype == object) or all(
2160-
not is_list_like(x) for x in nxt
2161-
)
2162-
2163-
# DataFrame is false positive of is_legal
2164-
# because "x in df" returns column names
2165-
if not is_legal or isinstance(nxt, DataFrame):
2166-
raise TypeError(err_msg)
2167-
2168-
nxt, wnx = self._get_series_list(nxt, ignore_index=ignore_index)
2169-
los = los + nxt
2170-
join_warn = join_warn or wnx
2171-
2172-
if depr_warn:
2173-
warnings.warn(
2174-
"list-likes other than Series, Index, or "
2175-
"np.ndarray WITHIN another list-like are "
2176-
"deprecated and will be removed in a future "
2177-
"version.",
2178-
FutureWarning,
2179-
stacklevel=4,
2180-
)
2181-
return (los, join_warn)
2112+
while others: # iterate through list and append each element
2113+
los = los + self._get_series_list(others.pop(0))
2114+
return los
2115+
# ... or just strings
21822116
elif all(not is_list_like(x) for x in others):
2183-
return ([Series(others, index=idx)], False)
2184-
raise TypeError(err_msg)
2117+
return [Series(others, index=idx)]
2118+
raise TypeError(
2119+
"others must be Series, Index, DataFrame, np.ndarrary "
2120+
"or list-like (either containing only strings or "
2121+
"containing only objects of type Series/Index/"
2122+
"np.ndarray[1-dim])"
2123+
)
21852124

21862125
@forbid_nonstring_types(["bytes", "mixed", "mixed-integer"])
2187-
def cat(self, others=None, sep=None, na_rep=None, join=None):
2126+
def cat(self, others=None, sep=None, na_rep=None, join="left"):
21882127
"""
21892128
Concatenate strings in the Series/Index with given separator.
21902129
@@ -2218,16 +2157,15 @@ def cat(self, others=None, sep=None, na_rep=None, join=None):
22182157
- If `na_rep` is None, and `others` is not None, a row containing a
22192158
missing value in any of the columns (before concatenation) will
22202159
have a missing value in the result.
2221-
join : {'left', 'right', 'outer', 'inner'}, default None
2160+
join : {'left', 'right', 'outer', 'inner'}, default 'left'
22222161
Determines the join-style between the calling Series/Index and any
22232162
Series/Index/DataFrame in `others` (objects without an index need
2224-
to match the length of the calling Series/Index). If None,
2225-
alignment is disabled, but this option will be removed in a future
2226-
version of pandas and replaced with a default of `'left'`. To
2227-
disable alignment, use `.values` on any Series/Index/DataFrame in
2228-
`others`.
2163+
to match the length of the calling Series/Index). To disable
2164+
alignment, use `.values` on any Series/Index/DataFrame in `others`.
22292165
22302166
.. versionadded:: 0.23.0
2167+
.. versionchanged:: 1.0.0
2168+
Changed default of `join` from None to `'left'`.
22312169
22322170
Returns
22332171
-------
@@ -2343,39 +2281,14 @@ def cat(self, others=None, sep=None, na_rep=None, join=None):
23432281

23442282
try:
23452283
# turn anything in "others" into lists of Series
2346-
others, warn = self._get_series_list(others, ignore_index=(join is None))
2284+
others = self._get_series_list(others)
23472285
except ValueError: # do not catch TypeError raised by _get_series_list
2348-
if join is None:
2349-
raise ValueError(
2350-
"All arrays must be same length, except "
2351-
"those having an index if `join` is not None"
2352-
)
2353-
else:
2354-
raise ValueError(
2355-
"If `others` contains arrays or lists (or "
2356-
"other list-likes without an index), these "
2357-
"must all be of the same length as the "
2358-
"calling Series/Index."
2359-
)
2360-
2361-
if join is None and warn:
2362-
warnings.warn(
2363-
"A future version of pandas will perform index "
2364-
"alignment when `others` is a Series/Index/"
2365-
"DataFrame (or a list-like containing one). To "
2366-
"disable alignment (the behavior before v.0.23) and "
2367-
"silence this warning, use `.values` on any Series/"
2368-
"Index/DataFrame in `others`. To enable alignment "
2369-
"and silence this warning, pass `join='left'|"
2370-
"'outer'|'inner'|'right'`. The future default will "
2371-
"be `join='left'`.",
2372-
FutureWarning,
2373-
stacklevel=3,
2286+
raise ValueError(
2287+
"If `others` contains arrays or lists (or other "
2288+
"list-likes without an index), these must all be "
2289+
"of the same length as the calling Series/Index."
23742290
)
23752291

2376-
# if join is None, _get_series_list already force-aligned indexes
2377-
join = "left" if join is None else join
2378-
23792292
# align if required
23802293
if any(not data.index.equals(x.index) for x in others):
23812294
# Need to add keys for uniqueness in case of duplicate columns

0 commit comments

Comments
 (0)