Repository: pandas-dev/pandas

Issue:
BUG: Series.get() on ExtensionArray with integer key not in index returns incorrect result
#### Code Sample, a copy-pastable example if possible

```python
In [1]: import pandas as pd

In [2]: import decimal

In [3]: from pandas.tests.extension.decimal.array import DecimalArray

In [4]: s = pd.Series(DecimalArray([decimal.Decimal(i) for i in range(10)]))

In [5]: s
Out[5]:
0    0
1    1
2    2
3    3
4    4
5    5
6    6
7    7
8    8
9    9
dtype: decimal

In [6]: s2 = s[::2]

In [7]: s2
Out[7]:
0    0
2    2
4    4
6    6
8    8
dtype: decimal

In [8]: s2.get(1)
Out[8]: Decimal('2')

In [9]: t = pd.Series([i for i in range(10)], dtype=float)

In [10]: t
Out[10]:
0    0.0
1    1.0
2    2.0
3    3.0
4    4.0
5    5.0
6    6.0
7    7.0
8    8.0
9    9.0
dtype: float64

In [11]: t2 = t[::2]

In [12]: t2
Out[12]:
0    0.0
2    2.0
4    4.0
6    6.0
8    8.0
dtype: float64

In [13]: t2.get(1)

In [14]: t2.get(1) is None
Out[14]: True
```
#### Problem description

It appears that I didn't fix all of the issues in #20885, as I missed an issue when creating #20882  .

If you have an integer index backing an `ExtensionArray`, and you do `.get(n)`, where `n` is not in the index, an incorrect result is returned.


#### Expected Output

In the example above, the value of `s2.get(1)` should be `None`, just as it is for `t2.get(1)`.

#### Output of ``pd.show_versions()``

<details>

INSTALLED VERSIONS
------------------
commit: None
python: 3.6.4.final.0
python-bits: 64
OS: Windows
OS-release: 10
machine: AMD64
processor: Intel64 Family 6 Model 60 Stepping 3, GenuineIntel
byteorder: little
LC_ALL: None
LANG: None
LOCALE: None.None

pandas: 0.23.0
pytest: 3.3.2
pip: 9.0.1
setuptools: 38.4.0
Cython: 0.27.3
numpy: 1.14.0
scipy: 1.0.0
pyarrow: None
xarray: None
IPython: 6.2.1
sphinx: 1.6.6
patsy: 0.5.0
dateutil: 2.6.1
pytz: 2017.3
blosc: None
bottleneck: 1.2.1
tables: 3.4.2
numexpr: 2.6.4
feather: None
matplotlib: 2.1.2
openpyxl: 2.4.10
xlrd: 1.1.0
xlwt: 1.3.0
xlsxwriter: 1.0.2
lxml: 4.1.1
bs4: 4.6.0
html5lib: 1.0.1
sqlalchemy: 1.2.1
pymysql: 0.7.11.None
psycopg2: None
jinja2: 2.10
s3fs: None
fastparquet: None
pandas_gbq: None
pandas_datareader: None

</details>



Discussion:

Resolving patch:
diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py
--- a/pandas/core/indexes/base.py
+++ b/pandas/core/indexes/base.py
@@ -2988,16 +2988,20 @@ def get_value(self, series, key):
         # use this, e.g. DatetimeIndex
         s = getattr(series, '_values', None)
         if isinstance(s, (ExtensionArray, Index)) and is_scalar(key):
-            # GH 20825
+            # GH 20882, 21257
             # Unify Index and ExtensionArray treatment
             # First try to convert the key to a location
-            # If that fails, see if key is an integer, and
+            # If that fails, raise a KeyError if an integer
+            # index, otherwise, see if key is an integer, and
             # try that
             try:
                 iloc = self.get_loc(key)
                 return s[iloc]
             except KeyError:
-                if is_integer(key):
+                if (len(self) > 0 and
+                        self.inferred_type in ['integer', 'boolean']):
+                    raise
+                elif is_integer(key):
                     return s[key]
 
         s = com._values_from_object(series)


Test patch:
diff --git a/pandas/tests/extension/base/getitem.py b/pandas/tests/extension/base/getitem.py
--- a/pandas/tests/extension/base/getitem.py
+++ b/pandas/tests/extension/base/getitem.py
@@ -130,7 +130,7 @@ def test_get(self, data):
         expected = s.iloc[[0, 1]]
         self.assert_series_equal(result, expected)
 
-        assert s.get(-1) == s.iloc[-1]
+        assert s.get(-1) is None
         assert s.get(s.index.max() + 1) is None
 
         s = pd.Series(data[:6], index=list('abcdef'))
@@ -147,6 +147,11 @@ def test_get(self, data):
         assert s.get(-1) == s.iloc[-1]
         assert s.get(len(s)) is None
 
+        # GH 21257
+        s = pd.Series(data)
+        s2 = s[::2]
+        assert s2.get(1) is None
+
     def test_take_sequence(self, data):
         result = pd.Series(data)[[0, 1, 3]]
         assert result.iloc[0] == data[0]
diff --git a/pandas/tests/series/indexing/test_indexing.py b/pandas/tests/series/indexing/test_indexing.py
--- a/pandas/tests/series/indexing/test_indexing.py
+++ b/pandas/tests/series/indexing/test_indexing.py
@@ -187,6 +187,49 @@ def test_getitem_box_float64(test_data):
     assert isinstance(value, np.float64)
 
 
+@pytest.mark.parametrize(
+    'arr',
+    [
+        np.random.randn(10),
+        tm.makeDateIndex(10, name='a').tz_localize(
+            tz='US/Eastern'),
+    ])
+def test_get(arr):
+    # GH 21260
+    s = Series(arr, index=[2 * i for i in range(len(arr))])
+    assert s.get(4) == s.iloc[2]
+
+    result = s.get([4, 6])
+    expected = s.iloc[[2, 3]]
+    tm.assert_series_equal(result, expected)
+
+    result = s.get(slice(2))
+    expected = s.iloc[[0, 1]]
+    tm.assert_series_equal(result, expected)
+
+    assert s.get(-1) is None
+    assert s.get(s.index.max() + 1) is None
+
+    s = Series(arr[:6], index=list('abcdef'))
+    assert s.get('c') == s.iloc[2]
+
+    result = s.get(slice('b', 'd'))
+    expected = s.iloc[[1, 2, 3]]
+    tm.assert_series_equal(result, expected)
+
+    result = s.get('Z')
+    assert result is None
+
+    assert s.get(4) == s.iloc[4]
+    assert s.get(-1) == s.iloc[-1]
+    assert s.get(len(s)) is None
+
+    # GH 21257
+    s = pd.Series(arr)
+    s2 = s[::2]
+    assert s2.get(1) is None
+
+
 def test_series_box_timestamp():
     rng = pd.date_range('20090415', '20090519', freq='B')
     ser = Series(rng)