Skip to content

Avoid accessing private loc methods #27383

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 13 commits into from
Jul 24, 2019
8 changes: 5 additions & 3 deletions pandas/core/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -2970,7 +2970,7 @@ def __getitem__(self, key):
else:
if is_iterator(key):
key = list(key)
indexer = self.loc._convert_to_indexer(key, axis=1, raise_missing=True)
indexer = self.loc._get_listlike_indexer(key, axis=1, raise_missing=True)[1]

# take() does not accept boolean indexers
if getattr(indexer, "dtype", None) == bool:
Expand Down Expand Up @@ -3456,7 +3456,7 @@ def __setitem__(self, key, value):

def _setitem_slice(self, key, value):
self._check_setitem_copy()
self.loc._setitem_with_indexer(key, value)
self.loc[key] = value

def _setitem_array(self, key, value):
# also raises Exception if object array with NA values
Expand All @@ -3476,7 +3476,9 @@ def _setitem_array(self, key, value):
for k1, k2 in zip(key, value.columns):
self[k1] = value[k2]
else:
indexer = self.loc._convert_to_indexer(key, axis=1)
indexer = self.loc._get_listlike_indexer(
Copy link
Contributor

Choose a reason for hiding this comment

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

self.columns.get_indexer(key)?

Copy link
Member Author

Choose a reason for hiding this comment

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

Looks like this returns something different, will have to keep digging

key, axis=1, raise_missing=False
)[1]
self._check_setitem_copy()
self.loc._setitem_with_indexer((slice(None), indexer), value)

Expand Down
38 changes: 17 additions & 21 deletions pandas/core/indexing.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ def _validate_key(self, key, axis: int):
"""
raise AbstractMethodError(self)

def _has_valid_tuple(self, key):
def _has_valid_tuple(self, key: Tuple):
""" check the key for valid keys across my indexer """
for i, k in enumerate(key):
if i >= self.obj.ndim:
Expand All @@ -236,7 +236,7 @@ def _has_valid_tuple(self, key):
"[{types}] types".format(types=self._valid_types)
)

def _is_nested_tuple_indexer(self, tup):
def _is_nested_tuple_indexer(self, tup: Tuple):
if any(isinstance(ax, MultiIndex) for ax in self.obj.axes):
return any(is_nested_tuple(tup, ax) for ax in self.obj.axes)
return False
Expand All @@ -260,7 +260,7 @@ def _convert_tuple(self, key, is_setter: bool = False):
keyidx.append(idx)
return tuple(keyidx)

def _convert_range(self, key, is_setter: bool = False):
def _convert_range(self, key: range, is_setter: bool = False):
""" convert a range argument """
return list(key)

Expand All @@ -270,7 +270,7 @@ def _convert_scalar_indexer(self, key, axis: int):
# a scalar
return ax._convert_scalar_indexer(key, kind=self.name)

def _convert_slice_indexer(self, key, axis: int):
def _convert_slice_indexer(self, key: slice, axis: int):
# if we are accessing via lowered dim, use the last dim
ax = self.obj._get_axis(min(axis, self.ndim - 1))
return ax._convert_slice_indexer(key, kind=self.name)
Expand Down Expand Up @@ -484,7 +484,7 @@ def setter(item, v):
if is_list_like_indexer(value) and getattr(value, "ndim", 1) > 0:

# we have an equal len Frame
if isinstance(value, ABCDataFrame) and value.ndim > 1:
if isinstance(value, ABCDataFrame):
sub_indexer = list(indexer)
multiindex_indexer = isinstance(labels, MultiIndex)

Expand Down Expand Up @@ -638,27 +638,23 @@ def _setitem_with_indexer_missing(self, indexer, value):
self.obj._maybe_update_cacher(clear=True)
return self.obj

def _align_series(self, indexer, ser, multiindex_indexer=False):
def _align_series(self, indexer, ser: ABCSeries, multiindex_indexer: bool = False):
"""
Parameters
----------
indexer : tuple, slice, scalar
The indexer used to get the locations that will be set to
`ser`

ser : pd.Series
The values to assign to the locations specified by `indexer`

multiindex_indexer : boolean, optional
Defaults to False. Should be set to True if `indexer` was from
a `pd.MultiIndex`, to avoid unnecessary broadcasting.


Returns
-------
`np.array` of `ser` broadcast to the appropriate shape for assignment
to the locations selected by `indexer`

"""
if isinstance(indexer, (slice, np.ndarray, list, Index)):
indexer = tuple([indexer])
Expand Down Expand Up @@ -734,7 +730,7 @@ def ravel(i):

raise ValueError("Incompatible indexer with Series")

def _align_frame(self, indexer, df):
def _align_frame(self, indexer, df: ABCDataFrame):
is_frame = self.obj.ndim == 2

if isinstance(indexer, tuple):
Expand Down Expand Up @@ -786,7 +782,7 @@ def _align_frame(self, indexer, df):

raise ValueError("Incompatible indexer with DataFrame")

def _getitem_tuple(self, tup):
def _getitem_tuple(self, tup: Tuple):
try:
return self._getitem_lowerdim(tup)
except IndexingError:
Expand All @@ -809,7 +805,7 @@ def _getitem_tuple(self, tup):

return retval

def _multi_take_opportunity(self, tup):
def _multi_take_opportunity(self, tup: Tuple):
"""
Check whether there is the possibility to use ``_multi_take``.
Currently the limit is that all axes being indexed must be indexed with
Expand All @@ -833,7 +829,7 @@ def _multi_take_opportunity(self, tup):

return True

def _multi_take(self, tup):
def _multi_take(self, tup: Tuple):
"""
Create the indexers for the passed tuple of keys, and execute the take
operation. This allows the take operation to be executed all at once -
Expand All @@ -859,7 +855,7 @@ def _multi_take(self, tup):
def _convert_for_reindex(self, key, axis: int):
return key

def _handle_lowerdim_multi_index_axis0(self, tup):
def _handle_lowerdim_multi_index_axis0(self, tup: Tuple):
# we have an axis0 multi-index, handle or raise
axis = self.axis or 0
try:
Expand All @@ -884,7 +880,7 @@ def _handle_lowerdim_multi_index_axis0(self, tup):

return None

def _getitem_lowerdim(self, tup):
def _getitem_lowerdim(self, tup: Tuple):

# we can directly get the axis result since the axis is specified
if self.axis is not None:
Expand Down Expand Up @@ -948,7 +944,7 @@ def _getitem_lowerdim(self, tup):

raise IndexingError("not applicable")

def _getitem_nested_tuple(self, tup):
def _getitem_nested_tuple(self, tup: Tuple):
# we have a nested tuple so have at least 1 multi-index level
# we should be able to match up the dimensionality here

Expand Down Expand Up @@ -1422,7 +1418,7 @@ def _getbool_axis(self, key, axis: int):
# caller is responsible for ensuring non-None axis
labels = self.obj._get_axis(axis)
key = check_bool_indexer(labels, key)
inds, = key.nonzero()
inds = key.nonzero()[0]
try:
return self.obj.take(inds, axis=axis)
except Exception as detail:
Expand Down Expand Up @@ -2037,7 +2033,7 @@ def _getitem_scalar(self, key):
values = self.obj._get_value(*key, takeable=True)
return values

def _validate_integer(self, key, axis):
def _validate_integer(self, key: int, axis: int):
"""
Check that 'key' is a valid position in the desired axis.

Expand All @@ -2062,7 +2058,7 @@ def _validate_integer(self, key, axis):
if key >= len_axis or key < -len_axis:
raise IndexError("single positional indexer is out-of-bounds")

def _getitem_tuple(self, tup):
def _getitem_tuple(self, tup: Tuple):

self._has_valid_tuple(tup)
try:
Expand Down Expand Up @@ -2160,7 +2156,7 @@ class _ScalarAccessIndexer(_NDFrameIndexer):
""" access scalars quickly """

def _convert_key(self, key, is_setter: bool = False):
return list(key)
raise AbstractMethodError(self)

def __getitem__(self, key):
if not isinstance(key, tuple):
Expand Down
4 changes: 2 additions & 2 deletions pandas/io/pytables.py
Original file line number Diff line number Diff line change
Expand Up @@ -3992,7 +3992,7 @@ def process_filter(field, filt):
filt = filt.union(Index(self.levels))

takers = op(axis_values, filt)
return obj.loc._getitem_axis(takers, axis=axis_number)
return obj.loc(axis=axis_number)[takers]

# this might be the name of a file IN an axis
elif field in axis_values:
Expand All @@ -4005,7 +4005,7 @@ def process_filter(field, filt):
if isinstance(obj, DataFrame):
axis_number = 1 - axis_number
takers = op(values, filt)
return obj.loc._getitem_axis(takers, axis=axis_number)
return obj.loc(axis=axis_number)[takers]

raise ValueError(
"cannot find the field [{field}] for "
Expand Down