From 5d643628fa2fb83f99afb0a9e742acb06bd83d98 Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Wed, 5 Feb 2020 15:43:12 -0800 Subject: [PATCH 1/4] REF: CategoricalIndex.get_value no longer needed --- pandas/core/indexes/category.py | 29 ---------------------------- pandas/core/indexing.py | 15 ++------------ pandas/core/series.py | 3 +++ pandas/tests/indexing/test_scalar.py | 16 +++++++++------ 4 files changed, 15 insertions(+), 48 deletions(-) diff --git a/pandas/core/indexes/category.py b/pandas/core/indexes/category.py index 718b6afb70e06..554d270b5bc63 100644 --- a/pandas/core/indexes/category.py +++ b/pandas/core/indexes/category.py @@ -478,35 +478,6 @@ def get_loc(self, key, method=None): except KeyError: raise KeyError(key) - def get_value(self, series: "Series", key: Any): - """ - Fast lookup of value from 1-dimensional ndarray. Only use this if you - know what you're doing - - Parameters - ---------- - series : Series - 1-dimensional array to take values from - key: : scalar - The value of this index at the position of the desired value, - otherwise the positional index of the desired value - - Returns - ------- - Any - The element of the series at the position indicated by the key - """ - k = key - try: - k = self._convert_scalar_indexer(k, kind="getitem") - indexer = self.get_loc(k) - return series.take([indexer])[0] - except (KeyError, TypeError): - pass - - # we might be a positional inexer - return Index.get_value(self, series, key) - @Appender(Index.where.__doc__) def where(self, cond, other=None): # TODO: Investigate an alternative implementation with diff --git a/pandas/core/indexing.py b/pandas/core/indexing.py index acbf05a74d118..3733cb47c28b0 100755 --- a/pandas/core/indexing.py +++ b/pandas/core/indexing.py @@ -2101,19 +2101,8 @@ def _convert_key(self, key, is_setter: bool = False): return list(key) for ax, i in zip(self.obj.axes, key): - if ax.is_integer(): - if not is_integer(i): - raise ValueError( - "At based indexing on an integer index " - "can only have integer indexers" - ) - else: - if is_integer(i) and not (ax.holds_integer() or ax.is_floating()): - raise ValueError( - "At based indexing on an non-integer " - "index can only have non-integer " - "indexers" - ) + ax._convert_scalar_indexer(i, "loc") + return key diff --git a/pandas/core/series.py b/pandas/core/series.py index 2a627aa879c7c..0727922322ac4 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -978,6 +978,9 @@ def _get_value(self, label, takeable: bool = False): """ if takeable: return self._values[label] + + # We assume that _convert_scalar_indexer has already been called, + # with kind="loc", if necessary, by the time we get here return self.index.get_value(self, label) def __setitem__(self, key, value): diff --git a/pandas/tests/indexing/test_scalar.py b/pandas/tests/indexing/test_scalar.py index 9e6446ebc8de7..6ba65693a62f1 100644 --- a/pandas/tests/indexing/test_scalar.py +++ b/pandas/tests/indexing/test_scalar.py @@ -136,29 +136,33 @@ def test_at_to_fail(self): result = s.at["a"] assert result == 1 msg = ( - "At based indexing on an non-integer index can only have " - "non-integer indexers" + "cannot do label indexing on " + r"with these indexers \[0\] of " ) - with pytest.raises(ValueError, match=msg): + with pytest.raises(TypeError, match=msg): s.at[0] + with pytest.raises(TypeError, match=msg): + s.loc[0] df = DataFrame({"A": [1, 2, 3]}, index=list("abc")) result = df.at["a", "A"] assert result == 1 - with pytest.raises(ValueError, match=msg): + with pytest.raises(TypeError, match=msg): df.at["a", 0] + with pytest.raises(TypeError, match=msg): + df.loc["a", 0] s = Series([1, 2, 3], index=[3, 2, 1]) result = s.at[1] assert result == 3 msg = "At based indexing on an integer index can only have integer indexers" - with pytest.raises(ValueError, match=msg): + with pytest.raises(KeyError, match="a"): s.at["a"] df = DataFrame({0: [1, 2, 3]}, index=[3, 2, 1]) result = df.at[1, 0] assert result == 3 - with pytest.raises(ValueError, match=msg): + with pytest.raises(KeyError, match="a"): df.at["a", 0] # GH 13822, incorrect error string with non-unique columns when missing From 4c2b4e5b028239ae961771df334679e22fb674b1 Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Thu, 6 Feb 2020 16:01:33 -0800 Subject: [PATCH 2/4] rebase fixup --- pandas/tests/indexing/test_scalar.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pandas/tests/indexing/test_scalar.py b/pandas/tests/indexing/test_scalar.py index 31945f699782b..312a0c6531cfb 100644 --- a/pandas/tests/indexing/test_scalar.py +++ b/pandas/tests/indexing/test_scalar.py @@ -171,7 +171,6 @@ def test_series_at_raises_key_error(self): ser = Series([1, 2, 3], index=[3, 2, 1]) result = ser.at[1] assert result == 3 - result = ser.loc[1] assert result == 3 From 8235b0a0e79b4f2f0ba62efb99f34fa56cf43c46 Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Thu, 6 Feb 2020 18:10:06 -0800 Subject: [PATCH 3/4] fixup unused import --- pandas/core/indexes/category.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/pandas/core/indexes/category.py b/pandas/core/indexes/category.py index cb6f7cdbab13b..7373f41daefa4 100644 --- a/pandas/core/indexes/category.py +++ b/pandas/core/indexes/category.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, Any, List +from typing import Any, List import warnings import numpy as np @@ -29,9 +29,6 @@ from pandas.core.indexes.extension import ExtensionIndex, inherit_names import pandas.core.missing as missing -if TYPE_CHECKING: - from pandas import Series - _index_doc_kwargs = dict(ibase._index_doc_kwargs) _index_doc_kwargs.update(dict(target_klass="CategoricalIndex")) From 57a1e210b3825129f2cc4c37f8437f4b25ffdad1 Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Fri, 7 Feb 2020 09:04:24 -0800 Subject: [PATCH 4/4] test for getitem with categorical --- pandas/tests/series/indexing/test_indexing.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/pandas/tests/series/indexing/test_indexing.py b/pandas/tests/series/indexing/test_indexing.py index fa5c75d5e4ad9..bb10b12d94628 100644 --- a/pandas/tests/series/indexing/test_indexing.py +++ b/pandas/tests/series/indexing/test_indexing.py @@ -564,6 +564,18 @@ def test_categorical_assigning_ops(): tm.assert_series_equal(s, exp) +def test_getitem_categorical_str(): + # GH#31765 + ser = pd.Series(range(5), index=pd.Categorical(["a", "b", "c", "a", "b"])) + result = ser["a"] + expected = ser.iloc[[0, 3]] + tm.assert_series_equal(result, expected) + + # Check the intermediate steps work as expected + result = ser.index.get_value(ser, "a") + tm.assert_series_equal(result, expected) + + def test_slice(string_series, object_series): numSlice = string_series[10:20] numSliceEnd = string_series[-10:]