Repository: pandas-dev/pandas

Issue:
Impossible to use any variant of ".real/.imag" without warning
After #27106, `Series.{real,imag}` raise a deprecation warning, which I guess is fair enough from the POV of getting rid of [things](https://github.com/pandas-dev/pandas/issues/18262#issuecomment-343932461) that came originally from subclassing ndarray.

```
>>> pd.Series([1, 2, 3]).real
__main__:1: FutureWarning: `real` has be deprecated and will be removed in a future verison
array([1, 2, 3], dtype=int64)
```

However, due to the way numpy and pandas still interact (with a lot of the `__array__` stuff behind the scenes), it is now *also* impossible to use `np.{real,imag}` without warning:

```
>>> np.real(pd.Series([1, 2, 3]))
C:\ProgramData\Miniconda3\envs\pandas-dev\lib\site-packages\numpy\lib\type_check.py:161: FutureWarning: `real` has be deprecated and will be removed in a future verison
  return val.real
array([1, 2, 3], dtype=int64)
```

I'm fine with whichever way is recommended, but there should be at least one way that does not raise warnings...?

@mroeschke @jreback 

PS. One might also use this chance to fix a typo: "[...] has be*en* deprecated [...]"


Discussion:
What can pandas do to avoid the warning from `np.real(Series)`? I don't see any option.

I'd recommend `np.real(Series.to_array())`
> What can pandas do to avoid the warning from `np.real(Series)`? I don't see any option.

The warning comes from pandas, not numpy:

https://github.com/pandas-dev/pandas/blob/d1accd032b648c9affd6dce1f81feb9c99422483/pandas/core/series.py#L954

Is there a way to distinguish a call `np.real(Series)` from `Series.real`? TBH I don't know the exact path of resolution for that well enough (through all that `__array__`-stuff). But I'm kind of imagining a hook that is only set through the Series-method, but not the np-array-route. Then it would be easy not to raise in the latter case.

> I'd recommend `np.real(Series.to_array())`

That recommendation could be part of the warning?
> The warning comes from pandas, not numpy:

Right. What I meant was `np.real(arraylike)` does something like `if hasattr(arraylike, 'real'): return array like.real` which will necessarily emit a warning, right?
Thanks for the explanation. In this case, I agree that it's hard to actually do something.

I'm kind of wondering why this deprecation was necessary at all, but I guess amending the warning to inform the user of `np.real(Series.to_array())` of `Series.to_array().real` would be useful?
A PR updating the error message would be welcome. Are you interested in
working on it?

On Mon, Jul 29, 2019 at 5:37 PM h-vetinari <notifications@github.com> wrote:

> Thanks for the explanation. In this case, I agree that it's hard to
> actually do something.
>
> I'm kind of wondering why this deprecation was necessary at all, but I
> guess amending the warning to inform the user of
> np.real(Series.to_array()) of Series.to_array().real would be useful?
>
> —
> You are receiving this because you commented.
> Reply to this email directly, view it on GitHub
> <https://github.com/pandas-dev/pandas/issues/27610?email_source=notifications&email_token=AAKAOITLHO3XIBO35X4BJ5DQB5WKVA5CNFSM4IHD6QEKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD3CGSWQ#issuecomment-516188506>,
> or mute the thread
> <https://github.com/notifications/unsubscribe-auth/AAKAOIVRN54N3DF52XQCIC3QB5WKVANCNFSM4IHD6QEA>
> .
>

> Are you interested in working on it?

That's trivial. Will try to do so later.

Resolving patch:
diff --git a/pandas/core/series.py b/pandas/core/series.py
--- a/pandas/core/series.py
+++ b/pandas/core/series.py
@@ -955,7 +955,9 @@ def real(self):
         .. deprecated:: 0.25.0
         """
         warnings.warn(
-            "`real` has be deprecated and will be removed in a future version",
+            "`real` is deprecated and will be removed in a future version. "
+            "To eliminate this warning for a Series `ser`, use "
+            "`np.real(ser.to_numpy())` or `ser.to_numpy().real`.",
             FutureWarning,
             stacklevel=2,
         )
@@ -973,7 +975,9 @@ def imag(self):
         .. deprecated:: 0.25.0
         """
         warnings.warn(
-            "`imag` has be deprecated and will be removed in a future version",
+            "`imag` is deprecated and will be removed in a future version. "
+            "To eliminate this warning for a Series `ser`, use "
+            "`np.imag(ser.to_numpy())` or `ser.to_numpy().imag`.",
             FutureWarning,
             stacklevel=2,
         )


Test patch: