Preserve None in Series unique
State: closed

- [X] closes #20866
- [X] tests added / passed
- [ ] passes `git diff upstream/master -u -- "*.py" | flake8 --diff`
- [ ] whatsnew entry


Labels:
name: Missing-data
description: np.nan, pd.NaT, pd.NA, dropna, isnull, interpolate
name: Reshaping
description: Concat, Merge/Join, Stack/Unstack, Explode

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

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

```diff
@@           Coverage Diff           @@
##           master   #20893   +/-   ##
=======================================
  Coverage   91.81%   91.81%           
=======================================
  Files         153      153           
  Lines       49481    49481           
=======================================
  Hits        45430    45430           
  Misses       4051     4051
```

| Flag | Coverage Δ | |
|---|---|---|
| #multiple | `90.21% <ø> (ø)` | :arrow_up: |
| #single | `41.85% <ø> (ø)` | :arrow_up: |


------

[Continue to review full report at Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/20893?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/20893?src=pr&el=footer). Last update [bd4332f...f106b58](https://codecov.io/gh/pandas-dev/pandas/pull/20893?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

can you update and see if you can fixup the regression here?
Updated to match pre-existing behavior. FWIW I don't think this is ideal as it still mangles `pd.NaT` and `np.nan` but I figured revert to what it was for 0.23 and I can open a separate issue to ensure that the NA values remain distinct in a later release

Ref:
https://github.com/pandas-dev/pandas/issues/20866#issuecomment-385767579
Thanks for looking into this!

Can you do a quick performance check? (just a `%timeit` before / after with a largish object series) Eg

```
In [81]: s = pd.Series(['a', 'b', 'c', None]*10000)

In [82]: %timeit s.unique()
3.18 ms ± 9.9 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
```

BTW, I agree we should maybe reconsider how missing-like values are treated here, as it is indeed not fully consistent that NaN / NaT are not kept separate.
Here are the perf comps

```python
# Master
In [5]: arr = np.array(['foo', 'bar', 'baz', None]* 10000)
In [6]: %timeit pd.unique(arr)
2.72 ms ± 21.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

# f106b581570c18fb7ec57b941e744daef50b4460
In [4]: arr = np.array(['foo', 'bar', 'baz', None]* 10000)
In [5]: %timeit pd.unique(arr)
2.78 ms ± 17 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
```

thanks @WillAyd