BUG/PERF: Use EA in Index.get_value
State: closed

Avoid converting the ExtensionArray to an ndarray.

Before

```
pandas/tests/arrays/categorical/test_indexing.py F                                                                                                   [100%]

========================================================================= FAILURES =========================================================================
______________________________________________________________________ test_series_at ______________________________________________________________________

    def test_series_at():
        arr = NonCoercaibleCategorical(['a', 'b', 'c'])
        ser = Series(arr)
>       result = ser.at[0]

pandas/tests/arrays/categorical/test_indexing.py:158:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
pandas/core/indexing.py:2266: in __getitem__
    return self.obj._get_value(*key, takeable=self._takeable)
pandas/core/series.py:1078: in _get_value
    return self.index.get_value(self._values, label)
pandas/core/indexes/base.py:4303: in get_value
    s = com.values_from_object(series)
pandas/_libs/lib.pyx:82: in pandas._libs.lib.values_from_object
    obj = func()
pandas/core/arrays/categorical.py:1509: in get_values
    return np.array(self)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <[ValueError("I cannot be converted.") raised in repr()] NonCoercaibleCategorical object at 0x113d8b6a0>, dtype = None

    def __array__(self, dtype=None):
>       raise ValueError("I cannot be converted.")
E       ValueError: I cannot be converted.

```

Perf:

```
In [3]: a = pd.Series(pd.Categorical(np.random.choice(list(string.ascii_letters[:10]), 10_000)))

In [4]: %timeit a.at[0]
143 µs ± 4.86 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

In [3]: a = pd.Series(pd.Categorical(np.random.choice(list(string.ascii_letters[:10]), 10_000)))

In [4]: %timeit a.at[0]
11.1 µs ± 95.2 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
```

---

Split from #24024

Labels:
name: Performance
description: Memory or execution speed performance
name: ExtensionArray
description: Extending pandas with custom dtypes or arrays.

Comments:
Hello @TomAugspurger! Thanks for submitting the PR.

 - There are no PEP8 issues in the file [`pandas/core/indexes/base.py`](https://github.com/TomAugspurger/pandas/blob/ac63e765bf5ed1efb4a315ae4ec8bf7f89c9600a/pandas/core/indexes/base.py) !

 - There are no PEP8 issues in the file [`pandas/tests/arrays/categorical/test_indexing.py`](https://github.com/TomAugspurger/pandas/blob/ac63e765bf5ed1efb4a315ae4ec8bf7f89c9600a/pandas/tests/arrays/categorical/test_indexing.py) !


# [Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/24204?src=pr&el=h1) Report
> Merging [#24204](https://codecov.io/gh/pandas-dev/pandas/pull/24204?src=pr&el=desc) into [master](https://codecov.io/gh/pandas-dev/pandas/commit/c5a47118d73a53a016a28103726b57e27924bf29?src=pr&el=desc) will **not change** coverage.
> The diff coverage is `100%`.

[![Impacted file tree graph](https://codecov.io/gh/pandas-dev/pandas/pull/24204/graphs/tree.svg?width=650&token=eZ4WkYLtcO&height=150&src=pr)](https://codecov.io/gh/pandas-dev/pandas/pull/24204?src=pr&el=tree)

```diff
@@           Coverage Diff           @@
##           master   #24204   +/-   ##
=======================================
  Coverage   92.21%   92.21%           
=======================================
  Files         162      162           
  Lines       51723    51723           
=======================================
  Hits        47694    47694           
  Misses       4029     4029
```

| Flag | Coverage Δ | |
|---|---|---|
| #multiple | `90.61% <100%> (ø)` | :arrow_up: |
| #single | `43.03% <100%> (ø)` | :arrow_up: |

| [Impacted Files](https://codecov.io/gh/pandas-dev/pandas/pull/24204?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pandas/core/indexes/base.py](https://codecov.io/gh/pandas-dev/pandas/pull/24204/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvaW5kZXhlcy9iYXNlLnB5) | `96.27% <100%> (ø)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/24204?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/24204?src=pr&el=footer). Last update [c5a4711...7a6a16d](https://codecov.io/gh/pandas-dev/pandas/pull/24204?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

# [Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/24204?src=pr&el=h1) Report
> Merging [#24204](https://codecov.io/gh/pandas-dev/pandas/pull/24204?src=pr&el=desc) into [master](https://codecov.io/gh/pandas-dev/pandas/commit/c5a47118d73a53a016a28103726b57e27924bf29?src=pr&el=desc) will **increase** coverage by `<.01%`.
> The diff coverage is `100%`.

[![Impacted file tree graph](https://codecov.io/gh/pandas-dev/pandas/pull/24204/graphs/tree.svg?width=650&token=eZ4WkYLtcO&height=150&src=pr)](https://codecov.io/gh/pandas-dev/pandas/pull/24204?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master   #24204      +/-   ##
==========================================
+ Coverage   92.21%   92.21%   +<.01%     
==========================================
  Files         162      162              
  Lines       51723    51761      +38     
==========================================
+ Hits        47694    47731      +37     
- Misses       4029     4030       +1
```

| Flag | Coverage Δ | |
|---|---|---|
| #multiple | `90.61% <100%> (ø)` | :arrow_up: |
| #single | `43% <100%> (-0.03%)` | :arrow_down: |

| [Impacted Files](https://codecov.io/gh/pandas-dev/pandas/pull/24204?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pandas/core/indexes/base.py](https://codecov.io/gh/pandas-dev/pandas/pull/24204/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvaW5kZXhlcy9iYXNlLnB5) | `96.27% <100%> (ø)` | :arrow_up: |
| [pandas/core/arrays/categorical.py](https://codecov.io/gh/pandas-dev/pandas/pull/24204/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvYXJyYXlzL2NhdGVnb3JpY2FsLnB5) | `95.3% <0%> (-0.1%)` | :arrow_down: |
| [pandas/core/generic.py](https://codecov.io/gh/pandas-dev/pandas/pull/24204/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvZ2VuZXJpYy5weQ==) | `96.65% <0%> (ø)` | :arrow_up: |
| [pandas/core/arrays/sparse.py](https://codecov.io/gh/pandas-dev/pandas/pull/24204/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvYXJyYXlzL3NwYXJzZS5weQ==) | `92.08% <0%> (ø)` | :arrow_up: |
| [pandas/core/arrays/base.py](https://codecov.io/gh/pandas-dev/pandas/pull/24204/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvYXJyYXlzL2Jhc2UucHk=) | `97.41% <0%> (ø)` | :arrow_up: |
| [pandas/core/indexes/category.py](https://codecov.io/gh/pandas-dev/pandas/pull/24204/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvaW5kZXhlcy9jYXRlZ29yeS5weQ==) | `97.9% <0%> (ø)` | :arrow_up: |
| [pandas/core/internals/blocks.py](https://codecov.io/gh/pandas-dev/pandas/pull/24204/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvaW50ZXJuYWxzL2Jsb2Nrcy5weQ==) | `93.81% <0%> (+0.13%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/24204?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/24204?src=pr&el=footer). Last update [c5a4711...49c5967](https://codecov.io/gh/pandas-dev/pandas/pull/24204?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

All green.
Opened https://github.com/pandas-dev/pandas/issues/24207 for followup.
thanks!