Skip to content

Commit 26329fc

Browse files
authored
REF: define _convert_to_indexer in Loc (#31585)
1 parent df5572c commit 26329fc

File tree

1 file changed

+81
-84
lines changed

1 file changed

+81
-84
lines changed

pandas/core/indexing.py

+81-84
Original file line numberDiff line numberDiff line change
@@ -566,7 +566,7 @@ def iat(self) -> "_iAtIndexer":
566566
return _iAtIndexer("iat", self)
567567

568568

569-
class _NDFrameIndexer(_NDFrameIndexerBase):
569+
class _LocationIndexer(_NDFrameIndexerBase):
570570
_valid_types: str
571571
axis = None
572572

@@ -1580,10 +1580,6 @@ def _validate_read_indexer(
15801580
def _convert_to_indexer(self, key, axis: int):
15811581
raise AbstractMethodError(self)
15821582

1583-
1584-
class _LocationIndexer(_NDFrameIndexer):
1585-
_takeable: bool = False
1586-
15871583
def __getitem__(self, key):
15881584
if type(key) is tuple:
15891585
key = tuple(com.apply_if_callable(x, self.obj) for x in key)
@@ -1614,94 +1610,17 @@ def _getbool_axis(self, key, axis: int):
16141610
inds = key.nonzero()[0]
16151611
return self.obj._take_with_is_copy(inds, axis=axis)
16161612

1617-
def _convert_to_indexer(self, key, axis: int):
1618-
"""
1619-
Convert indexing key into something we can use to do actual fancy
1620-
indexing on a ndarray.
1621-
1622-
Examples
1623-
ix[:5] -> slice(0, 5)
1624-
ix[[1,2,3]] -> [1,2,3]
1625-
ix[['foo', 'bar', 'baz']] -> [i, j, k] (indices of foo, bar, baz)
1626-
1627-
Going by Zen of Python?
1628-
'In the face of ambiguity, refuse the temptation to guess.'
1629-
raise AmbiguousIndexError with integer labels?
1630-
- No, prefer label-based indexing
1631-
"""
1632-
labels = self.obj._get_axis(axis)
1633-
1634-
if isinstance(key, slice):
1635-
return self._convert_slice_indexer(key, axis)
1636-
1637-
# try to find out correct indexer, if not type correct raise
1638-
try:
1639-
key = self._convert_scalar_indexer(key, axis)
1640-
except TypeError:
1641-
# but we will allow setting
1642-
pass
1643-
1644-
# see if we are positional in nature
1645-
is_int_index = labels.is_integer()
1646-
is_int_positional = is_integer(key) and not is_int_index
1647-
1648-
if is_scalar(key) or isinstance(labels, ABCMultiIndex):
1649-
# Otherwise get_loc will raise InvalidIndexError
1650-
1651-
# if we are a label return me
1652-
try:
1653-
return labels.get_loc(key)
1654-
except LookupError:
1655-
if isinstance(key, tuple) and isinstance(labels, ABCMultiIndex):
1656-
if len(key) == labels.nlevels:
1657-
return {"key": key}
1658-
raise
1659-
except TypeError:
1660-
pass
1661-
except ValueError:
1662-
if not is_int_positional:
1663-
raise
1664-
1665-
# a positional
1666-
if is_int_positional:
1667-
1668-
# if we are setting and its not a valid location
1669-
# its an insert which fails by definition
1670-
1671-
# always valid
1672-
return {"key": key}
1673-
1674-
if is_nested_tuple(key, labels):
1675-
return labels.get_locs(key)
1676-
1677-
elif is_list_like_indexer(key):
1678-
1679-
if com.is_bool_indexer(key):
1680-
key = check_bool_indexer(labels, key)
1681-
(inds,) = key.nonzero()
1682-
return inds
1683-
else:
1684-
# When setting, missing keys are not allowed, even with .loc:
1685-
return self._get_listlike_indexer(key, axis, raise_missing=True)[1]
1686-
else:
1687-
try:
1688-
return labels.get_loc(key)
1689-
except LookupError:
1690-
# allow a not found key only if we are a setter
1691-
if not is_list_like_indexer(key):
1692-
return {"key": key}
1693-
raise
1694-
16951613

16961614
@Appender(IndexingMixin.loc.__doc__)
16971615
class _LocIndexer(_LocationIndexer):
1616+
_takeable: bool = False
16981617
_valid_types = (
16991618
"labels (MUST BE IN THE INDEX), slices of labels (BOTH "
17001619
"endpoints included! Can be slices of integers if the "
17011620
"index is integers), listlike of labels, boolean"
17021621
)
17031622

1704-
@Appender(_NDFrameIndexer._validate_key.__doc__)
1623+
@Appender(_LocationIndexer._validate_key.__doc__)
17051624
def _validate_key(self, key, axis: int):
17061625

17071626
# valid for a collection of labels (we check their presence later)
@@ -1867,6 +1786,84 @@ def _get_slice_axis(self, slice_obj: slice, axis: int):
18671786
# return a DatetimeIndex instead of a slice object.
18681787
return self.obj.take(indexer, axis=axis)
18691788

1789+
def _convert_to_indexer(self, key, axis: int):
1790+
"""
1791+
Convert indexing key into something we can use to do actual fancy
1792+
indexing on a ndarray.
1793+
1794+
Examples
1795+
ix[:5] -> slice(0, 5)
1796+
ix[[1,2,3]] -> [1,2,3]
1797+
ix[['foo', 'bar', 'baz']] -> [i, j, k] (indices of foo, bar, baz)
1798+
1799+
Going by Zen of Python?
1800+
'In the face of ambiguity, refuse the temptation to guess.'
1801+
raise AmbiguousIndexError with integer labels?
1802+
- No, prefer label-based indexing
1803+
"""
1804+
labels = self.obj._get_axis(axis)
1805+
1806+
if isinstance(key, slice):
1807+
return self._convert_slice_indexer(key, axis)
1808+
1809+
# try to find out correct indexer, if not type correct raise
1810+
try:
1811+
key = self._convert_scalar_indexer(key, axis)
1812+
except TypeError:
1813+
# but we will allow setting
1814+
pass
1815+
1816+
# see if we are positional in nature
1817+
is_int_index = labels.is_integer()
1818+
is_int_positional = is_integer(key) and not is_int_index
1819+
1820+
if is_scalar(key) or isinstance(labels, ABCMultiIndex):
1821+
# Otherwise get_loc will raise InvalidIndexError
1822+
1823+
# if we are a label return me
1824+
try:
1825+
return labels.get_loc(key)
1826+
except LookupError:
1827+
if isinstance(key, tuple) and isinstance(labels, ABCMultiIndex):
1828+
if len(key) == labels.nlevels:
1829+
return {"key": key}
1830+
raise
1831+
except TypeError:
1832+
pass
1833+
except ValueError:
1834+
if not is_int_positional:
1835+
raise
1836+
1837+
# a positional
1838+
if is_int_positional:
1839+
1840+
# if we are setting and its not a valid location
1841+
# its an insert which fails by definition
1842+
1843+
# always valid
1844+
return {"key": key}
1845+
1846+
if is_nested_tuple(key, labels):
1847+
return labels.get_locs(key)
1848+
1849+
elif is_list_like_indexer(key):
1850+
1851+
if com.is_bool_indexer(key):
1852+
key = check_bool_indexer(labels, key)
1853+
(inds,) = key.nonzero()
1854+
return inds
1855+
else:
1856+
# When setting, missing keys are not allowed, even with .loc:
1857+
return self._get_listlike_indexer(key, axis, raise_missing=True)[1]
1858+
else:
1859+
try:
1860+
return labels.get_loc(key)
1861+
except LookupError:
1862+
# allow a not found key only if we are a setter
1863+
if not is_list_like_indexer(key):
1864+
return {"key": key}
1865+
raise
1866+
18701867

18711868
@Appender(IndexingMixin.iloc.__doc__)
18721869
class _iLocIndexer(_LocationIndexer):

0 commit comments

Comments
 (0)