Skip to content

REF: de-nest Series getitem/setitem checks #33447

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

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 44 additions & 47 deletions pandas/core/series.py
Original file line number Diff line number Diff line change
Expand Up @@ -880,6 +880,17 @@ def __getitem__(self, key):
if isinstance(key, (list, tuple)):
key = unpack_1tuple(key)

if isinstance(key, slice):
# _convert_slice_indexer to determin if this slice is positional
# or label based, and if the latter, convert to positional
slobj = self.index._convert_slice_indexer(key, kind="getitem")
return self._slice(slobj)

elif com.is_bool_indexer(key):
key = check_bool_indexer(self.index, key)
key = np.asarray(key, dtype=bool)
return self._get_values(key)

if key_is_scalar or isinstance(self.index, MultiIndex):
# Otherwise index.get_value will raise InvalidIndexError
try:
Expand All @@ -897,26 +908,14 @@ def __getitem__(self, key):
else:
raise

if not key_is_scalar:
# avoid expensive checks if we know we have a scalar
Copy link
Member

Choose a reason for hiding this comment

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

This comment might be relevant? Also if you move it up as you did now, you can keep this scalar check?

if is_iterator(key):
key = list(key)

if com.is_bool_indexer(key):
key = check_bool_indexer(self.index, key)
key = np.asarray(key, dtype=bool)
return self._get_values(key)
if is_iterator(key):
key = list(key)

return self._get_with(key)

def _get_with(self, key):
# other: fancy integer or otherwise
if isinstance(key, slice):
# _convert_slice_indexer to determin if this slice is positional
# or label based, and if the latter, convert to positional
slobj = self.index._convert_slice_indexer(key, kind="getitem")
return self._slice(slobj)
elif isinstance(key, ABCDataFrame):
if isinstance(key, ABCDataFrame):
raise TypeError(
"Indexing a Series with DataFrame is not "
"supported, use the appropriate DataFrame column"
Expand Down Expand Up @@ -1009,6 +1008,19 @@ def __setitem__(self, key, value):
if key is Ellipsis:
key = slice(None)

if isinstance(key, slice):
indexer = self.index._convert_slice_indexer(key, kind="getitem")
return self._set_values(indexer, value)

elif com.is_bool_indexer(key):
key = check_bool_indexer(self.index, key)
key = np.asarray(key, dtype=bool)
try:
self._where(~key, value, inplace=True)
except InvalidIndexError:
self._set_values(key.astype(np.bool_), value)
return

try:
self._set_with_engine(key, value)
except (KeyError, ValueError):
Expand All @@ -1024,17 +1036,7 @@ def __setitem__(self, key, value):
if isinstance(key, tuple) and not isinstance(self.index, MultiIndex):
raise ValueError("Can only tuple-index with a MultiIndex") from e

if com.is_bool_indexer(key):
key = check_bool_indexer(self.index, key)
key = np.asarray(key, dtype=bool)
try:
self._where(~key, value, inplace=True)
except InvalidIndexError:
self._set_values(key.astype(np.bool_), value)
return

else:
self._set_with(key, value)
self._set_with(key, value)

if cacher_needs_updating:
self._maybe_update_cacher()
Expand All @@ -1047,31 +1049,26 @@ def _set_with_engine(self, key, value):

def _set_with(self, key, value):
# other: fancy integer or otherwise
if isinstance(key, slice):
indexer = self.index._convert_slice_indexer(key, kind="getitem")
return self._set_values(indexer, value)
assert not isinstance(key, tuple)

else:
assert not isinstance(key, tuple)
if is_scalar(key):
key = [key]

if is_scalar(key):
key = [key]

if isinstance(key, Index):
key_type = key.inferred_type
key = key._values
else:
key_type = lib.infer_dtype(key, skipna=False)
if isinstance(key, Index):
key_type = key.inferred_type
key = key._values
else:
key_type = lib.infer_dtype(key, skipna=False)

# Note: key_type == "boolean" should not occur because that
# should be caught by the is_bool_indexer check in __setitem__
if key_type == "integer":
if self.index.inferred_type == "integer":
self._set_labels(key, value)
else:
self._set_values(key, value)
else:
# Note: key_type == "boolean" should not occur because that
# should be caught by the is_bool_indexer check in __setitem__
if key_type == "integer":
if self.index.inferred_type == "integer":
self._set_labels(key, value)
else:
self._set_values(key, value)
else:
self._set_labels(key, value)

def _set_labels(self, key, value):
key = com.asarray_tuplesafe(key)
Expand Down