Additional tests for ufunc(Series)
State: closed

This adds a set of tests for ufuncs on Series. The goal is to
establish the correct behavior prior to implementing `Series.__array_ufunc__`.

There are two kinds of xfails right now

1. Series[Sparse] fails because `Series.__array_ufunc__` doesn't
    yet dispatch to `Series.array.__array_ufunc__`
2. `ufunc(series, series)` when the two series are unaligned. It's
    been determined that these should align, but isn't currently
    implemented.

LMK if there's anything I can do to make these tests clearer. The heavy parameterization is a bit unfortunate, but I think the best option.

xref https://github.com/pandas-dev/pandas/pull/23293

Labels:
name: Testing
description: pandas testing functions or related to the test suite
name: Numeric Operations
description: Arithmetic, Comparison, and Logical operations

Comments:
Should DTA[tz] be included along with Sparse?
# [Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/26951?src=pr&el=h1) Report
> Merging [#26951](https://codecov.io/gh/pandas-dev/pandas/pull/26951?src=pr&el=desc) into [master](https://codecov.io/gh/pandas-dev/pandas/commit/224362951942e1f4e05fb8948596620aedac26d9?src=pr&el=desc) will **increase** coverage by `<.01%`.
> The diff coverage is `n/a`.

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

```diff
@@            Coverage Diff             @@
##           master   #26951      +/-   ##
==========================================
+ Coverage   91.98%   91.98%   +<.01%     
==========================================
  Files         180      180              
  Lines       50772    50774       +2     
==========================================
+ Hits        46704    46706       +2     
  Misses       4068     4068
```

| Flag | Coverage Δ | |
|---|---|---|
| #multiple | `90.62% <ø> (+0.05%)` | :arrow_up: |
| #single | `41.85% <ø> (-0.06%)` | :arrow_down: |

| [Impacted Files](https://codecov.io/gh/pandas-dev/pandas/pull/26951?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pandas/io/gbq.py](https://codecov.io/gh/pandas-dev/pandas/pull/26951/diff?src=pr&el=tree#diff-cGFuZGFzL2lvL2dicS5weQ==) | `88.88% <0%> (-11.12%)` | :arrow_down: |
| [pandas/core/frame.py](https://codecov.io/gh/pandas-dev/pandas/pull/26951/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvZnJhbWUucHk=) | `96.89% <0%> (-0.12%)` | :arrow_down: |
| [pandas/io/pytables.py](https://codecov.io/gh/pandas-dev/pandas/pull/26951/diff?src=pr&el=tree#diff-cGFuZGFzL2lvL3B5dGFibGVzLnB5) | `90.3% <0%> (ø)` | :arrow_up: |
| [pandas/core/arrays/sparse.py](https://codecov.io/gh/pandas-dev/pandas/pull/26951/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvYXJyYXlzL3NwYXJzZS5weQ==) | `94.19% <0%> (+0.46%)` | :arrow_up: |

------

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

> Should DTA[tz] be included along with Sparse?

IMO, the intention of these tests is to verify the correctness of the future `Series.__array_ufunc__`. I parametrize over `Series[int]` and `Series[Sparse[int]]` to verify the correctness of the dispatch to array logic. In *theory* the dispatch logic will handle all arrays the same. I'll add a small sanity test, separate from the rest, since the set of ufuncs valid for datetime64 is different.
OK, many of the DTA[tz] ufuncs are currently broken, so its OK by me if you want to leave them out.
0b1e745 adds another xfail for `ufunc(Index, Series)`, e.g. `np.add(index, series)`. Right now that returns an Index

```python
In [1]: import pandas as pd; import numpy as np

In [2]: a = pd.Series([1, 2])

In [3]: b = pd.Index([1, 2])

In [4]: np.add(b, a)
Out[4]: Int64Index([2, 4], dtype='int64')
```

I think that's a bug. It's inconsistent with the binop

```python
In [5]: b + a
Out[5]:
0    2
1    4
dtype: int64
```

So the rule is that `Index.__array_ufunc__` should check the `types` for Series. If any are found then it should return NotImplemented, so that `Series.__array_ufunc__` can take over.
https://github.com/pandas-dev/pandas/pull/26951/commits/775c2efde0f84dc7f1a2c214bc6d8a0bd21f1d4d fixes an issue with one of the tests. The test wasn't correct for `ufunc(a, b)` when we shuffle b (to force alignment). It was passing earlier, since we xfail `shuffle=True` for now.

I think this PR should be ready to go. I'd like to merge Joris' `array_ufunc` branch on top of it to actually start fixing the xfails.


do we have an issue for this? (or maybe just xref the actual ufunc issue at the top of the PR)
Changes

* split the binop ufunc test into three: with array, with index, with Series. Simplified things quite a bit I think
* Cleaned up the names. Hopefully `array_args` and `series_args` make things much clearer that `a, b, c, d`.
lgtm.
thanks @TomAugspurger