8000 API: str.cat will align on Series by h-vetinari · Pull Request #20347 · pandas-dev/pandas · GitHub
[go: up one dir, main page]

Skip to content

API: str.cat will align on Series #20347

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
May 2, 2018
Prev Previous commit
Next Next commit
Avoid deep inspection for known types in _get_series_list
  • Loading branch information
h-vetinari committed May 2, 2018
commit 5a237ea61a4d7690966bb5dc8630c18b9fa35542
2 changes: 1 addition & 1 deletion doc/source/text.rst
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ All one-dimensional list-likes can be arbitrarily combined in a list-like contai

s
u
s.str.cat([u, pd.Index(u.values), ['A', 'B', 'C', 'D']], na_rep='-')
s.str.cat([u, pd.Index(u.values), ['A', 'B', 'C', 'D'], map(int, u.index)], na_rep='-')

All elements must match in length to the calling ``Series`` (or ``Index``), except those having an index if ``join`` is not None:

Expand Down
33 changes: 19 additions & 14 deletions pandas/core/strings.py
Original file line number Diff line number Diff line change
Expand Up @@ -1979,8 +1979,8 @@ def _get_series_list(self, others, ignore_index=False):
elif isinstance(others, DataFrame):
fut_warn = not others.index.equals(idx)
if ignore_index and fut_warn:
# without copy, this could change (the corresponding list
# element of) "others" that was passed to str.cat
# without copy, this could change "others"
# that was passed to str.cat
others = others.copy()
others.index = idx
return ([others[x] for x in others], fut_warn)
Expand All @@ -1993,22 +1993,27 @@ def _get_series_list(self, others, ignore_index=False):
los = []
fut_warn = False
while others:
nxt = others.pop(0)
# safety for iterators etc.; nxt is list-like as per above
# do not map indexed objects, which would lose their index
if not isinstance(nxt, (DataFrame, Series, Index)):
nxt = others.pop(0) # list-like as per check above
# safety for iterators and other non-persistent list-likes
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this whole section needs some work it’s way too hard to read and follow

# do not map indexed/typed objects; would lose information
if not isinstance(nxt, (DataFrame, Series,
Index, np.ndarray)):
nxt = list(nxt)

# Nested list-likes are forbidden - content of nxt must be
# strings/NaN/None. Need to robustify check against
# x in nxt being list-like (otherwise ambiguous boolean).
is_legal = all((isinstance(x, compat.string_types)
or (not is_list_like(x) and isnull(x))
or x is None)
for x in nxt)
# known types without deep inspection
no_deep = ((isinstance(nxt, np.ndarray) and nxt.ndim == 1)
or isinstance(nxt, (Series, Index)))
# Nested list-likes are forbidden - elements of nxt must be
# strings/NaN/None. Need to robustify NaN-check against
# x in nxt being list-like (otherwise ambiguous boolean)
is_legal = ((no_deep and nxt.dtype == object)
or all((isinstance(x, compat.string_types)
or (not is_list_like(x) and isnull(x))
or x is None)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isnull already checks for None
only 1d objects are valid here (or all scalars)

do this check up front

for x in nxt))
# DataFrame is false positive of is_legal
# because "x in df" returns column names
if isinstance(nxt, DataFrame) or not is_legal:
if not is_legal or isinstance(nxt, DataFrame):
raise TypeError(err_msg)

tmp = self._get_series_list(nxt, ignore_index=ignore_index)
Expand Down
2 changes: 1 addition & 1 deletion pandas/tests/test_strings.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import pandas.core.strings as strings


def assert_series_or_index_equal(left, right, expect_warn=False):
def assert_series_or_index_equal(left, right):
if isinstance(left, Series):
assert_series_equal(left, right)
else: # Index
Expand Down
0