API: ExtensionArray.argsort places the missing value at the end 
State: closed

continue #26354 

1. Categorical will be handled in a separate PR.
2. benchmark result:
```
       before           after         ratio
     [989f912e]       [dc0ef701]
     <master>         <enh-21801-2>
+     11.4±0.03μs       36.8±0.1μs     3.23  algorithms.EASorting.time_argsort(1000)
+       785±0.5μs      1.26±0.03ms     1.60  algorithms.EASorting.time_argsort(100000)

```

xref https://github.com/pandas-dev/pandas/issues/21801 (doesn't close; Need to update existing EAs)

Labels:
name: Missing-data
description: np.nan, pd.NaT, pd.NA, dropna, isnull, interpolate
name: ExtensionArray
description: Extending pandas with custom dtypes or arrays.

Comments:
FYI @jorisvandenbossche just doing the breaking Categorical change here.
As expected, a few failures in our test suite. Going through them next.

I think https://travis-ci.org/pandas-dev/pandas/jobs/553767675#L2498 is buggy / defined strangely.  (DataFrame.sort_index with a CategoricalIndex and ascending=False)



```python
# 0.24
In [2]: df = pd.DataFrame({"A": list(range(6))}, index=pd.Categorical(['a', 'a', 'b', 'b', 'c', 'a'], categories=['c', 'a', 'b']))

In [3]: df.sort_index(ascending=False)
Out[3]:
   A
b  3
b  2
a  5
a  1
a  0
c  4

In [4]: df.set_index(df.index.codes).sort_index(ascending=False)
Out[4]:
   A
2  2
2  3
1  0
1  1
1  5
0  4

```

```python
# this PR

In [3]: df.sort_index()
Out[3]:
   A
c  4
a  0
a  1
a  5
b  2
b  3

In [4]: df.set_index(df.index.codes).sort_index()
Out[4]:
   A
0  4
1  0
1  1
1  5
2  2
2  3
```

I think that sorting by a CategoricalIndex should be the same as sorting by its codes. 0.24 (and master, before the PR)  doesn't have that property.
It's probably more a comment on the changes in https://github.com/pandas-dev/pandas/pull/26854, but it seems that `nargsort` is now always calling `_values_for_argsort` for EAs. But, in the comments of `ExtensionArray.argsort`, we say that there are two ways to override argsort: have `_values_for_argsort`, or implement `argsort` yourself for full control. 

So the current indirection seems a bit wrong. At least depending on where `nargsort` is called internally, it should call the `argsort` method of the EA, to let the EA have full control over it. 

(but that is maybe not blocking for the RC, most important is to get the actual behaviour change in)
Hmm, so we would want to tell users that they should *always* override `_values_for_argsort`, since just doing `.argsort` may not be enough. OK, I'll try to write something about that.
> Hmm, so we would want to tell users that they should always override _values_for_argsort, since just doing .argsort may not be enough.

Not fully sure. We *could* also pass `_values_for_argsort` to `nargsort` from withing EA.argsort, and let `nargsort` call `EA.argsort` (I think, might be missing something in this indirection web).
I'm also having trouble with the indirection.

AFAICT, with this PR we end up in a situation where `ExtensionArray.argsort` could differ from other places in pandas that do `nargsort(ExtensionArray)`. Since `nargsort` Does pandas' usual sorting algo on the `ExtensionArray._values_for_argsort`...
All green. I had to slightly adjust the test in https://github.com/pandas-dev/pandas/pull/27137/commits/47c6b57bb7d2b7959f5f96db6aeebe803d2dc1b0

I don't have a 32-bit machine to test on, but it seems like we may be inconsistent with whether `_values_for_argsort` returns an int32 or int64 dtype array. It doesn't seem to matter in the algorithm, so I cast to int64 before making the assert.
> All green. I had to slightly adjust the test in [47c6b57](https://github.com/pandas-dev/pandas/commit/47c6b57bb7d2b7959f5f96db6aeebe803d2dc1b0)
> 
> I don't have a 32-bit machine to test on, but it seems like we may be inconsistent with whether `_values_for_argsort` returns an int32 or int64 dtype array. It doesn't seem to matter in the algorithm, so I cast to int64 before making the assert.

I believe this will break on the 32-bit builds; argsort is supposed to return platform ints.

So I guess our current interface is kind wrong. But let's merge this and consider that.
> AFAICT, with this PR we end up in a situation where ExtensionArray.argsort could differ from other places in pandas that do nargsort(ExtensionArray). Since nargsort Does pandas' usual sorting on the ExtensionArray._values_for_argsort...

Let's open an issue about that to fix after the RC before final 0.25.0 ?
Writing one now.

On Wed, Jul 3, 2019 at 3:48 PM Joris Van den Bossche <
notifications@github.com> wrote:

> AFAICT, with this PR we end up in a situation where ExtensionArray.argsort
> could differ from other places in pandas that do nargsort(ExtensionArray).
> Since nargsort Does pandas' usual sorting on the
> ExtensionArray._values_for_argsort...
>
> Let's open an issue about that to fix after the RC before final 0.25.0 ?
>
> —
> You are receiving this because you commented.
> Reply to this email directly, view it on GitHub
> <https://github.com/pandas-dev/pandas/pull/27137?email_source=notifications&email_token=AAKAOIW4K5LZLPQF6565JFLP5UGDHA5CNFSM4H4LZM7KYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODZFUMEQ#issuecomment-508249618>,
> or mute the thread
> <https://github.com/notifications/unsubscribe-auth/AAKAOIQWYYAC45IW5HCW3W3P5UGDHANCNFSM4H4LZM7A>
> .
>

https://github.com/pandas-dev/pandas/issues/27218, but my thinking on this
may be a bit unclear.

On Wed, Jul 3, 2019 at 3:49 PM Tom Augspurger <tom.augspurger88@gmail.com>
wrote:

> Writing one now.
>
> On Wed, Jul 3, 2019 at 3:48 PM Joris Van den Bossche <
> notifications@github.com> wrote:
>
>> AFAICT, with this PR we end up in a situation where
>> ExtensionArray.argsort could differ from other places in pandas that do
>> nargsort(ExtensionArray). Since nargsort Does pandas' usual sorting on the
>> ExtensionArray._values_for_argsort...
>>
>> Let's open an issue about that to fix after the RC before final 0.25.0 ?
>>
>> —
>> You are receiving this because you commented.
>> Reply to this email directly, view it on GitHub
>> <https://github.com/pandas-dev/pandas/pull/27137?email_source=notifications&email_token=AAKAOIW4K5LZLPQF6565JFLP5UGDHA5CNFSM4H4LZM7KYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODZFUMEQ#issuecomment-508249618>,
>> or mute the thread
>> <https://github.com/notifications/unsubscribe-auth/AAKAOIQWYYAC45IW5HCW3W3P5UGDHANCNFSM4H4LZM7A>
>> .
>>
>