Repository: pandas-dev/pandas

Issue:
Series is missing real/imag attributes
The `Series` class in 0.10 had a `real` and  a `imag` attribute but in 0.12dev these attrs are missing. This probably happend during the refactoring of the Series class for 0.12.

``` python
In [1]: pd.__version__
Out[1]: '0.10.0'

In [2]: a = np.arange(5)

In [3]: b = pd.Series(a + 4j*a)

In [4]: b.real
Out[4]: 
0    0
1    1
2    2
3    3
4    4
```

``` python
In [1]: pd.__version__
Out[1]: '0.12.0-381-g15d5f0a'

In [2]: a = np.arange(5)

In [3]: b = pd.Series(a + 4j*a)

In [4]: b.real
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-4-ec5ddb077f9e> in <module>()
----> 1 b.real

/usr/lib64/python2.7/site-packages/pandas-0.12.0_381_g15d5f0a-py2.7-linux-x86_64.egg/pandas/core/generic.pyc in __getattr__(self, name)
   1287             return self[name]
   1288         raise AttributeError("'%s' object has no attribute '%s'" %
-> 1289                              (type(self).__name__, name))
   1290 
   1291     def __setattr__(self, name, value):

AttributeError: 'Series' object has no attribute 'real'
```



Discussion:
you can access like below

These are easy to do (just a delegated property), but is this a typical access pattern?

should we make them methods? what do you do with the complex numbers?

```
In [1]: a = np.arange(5)

In [2]: 

In [2]: In [3]: b = pd.Series(a + 4j*a)

In [3]: b
Out[3]: 
0         0j
1     (1+4j)
2     (2+8j)
3    (3+12j)
4    (4+16j)
dtype: complex128

In [4]: b.values
Out[4]: array([ 0. +0.j,  1. +4.j,  2. +8.j,  3.+12.j,  4.+16.j])

In [5]: b.values.real
Out[5]: array([ 0.,  1.,  2.,  3.,  4.])

In [6]: b.values.imag
Out[6]: array([  0.,   4.,   8.,  12.,  16.])
```

I know that - actually, this is what I'm using as a workaround in 0.12dev. Is it intentional that the 'new' Series class does not contain these attrs anymore?

nope...they are apparently properties on numpy ararys; we didn't have any tests that use these so they weren't 'missing'. I'll add them..pretty easy


Resolving patch:
diff --git a/pandas/core/series.py b/pandas/core/series.py
--- a/pandas/core/series.py
+++ b/pandas/core/series.py
@@ -35,6 +35,7 @@
 from pandas import compat
 from pandas.util.terminal import get_terminal_size
 from pandas.compat import zip, lzip, u, OrderedDict
+from pandas.util import rwproperty
 
 import pandas.core.array as pa
 
@@ -793,6 +794,23 @@ def __array_wrap__(self, result):
     def __contains__(self, key):
         return key in self.index
 
+    # complex
+    @rwproperty.getproperty
+    def real(self):
+        return self.values.real
+
+    @rwproperty.setproperty
+    def real(self, v):
+        self.values.real = v
+
+    @rwproperty.getproperty
+    def imag(self):
+        return self.values.imag
+
+    @rwproperty.setproperty
+    def imag(self, v):
+        self.values.imag = v
+
     # coercion
     __float__ = _coerce_method(float)
     __long__ = _coerce_method(int)


Test patch:
diff --git a/pandas/tests/test_series.py b/pandas/tests/test_series.py
--- a/pandas/tests/test_series.py
+++ b/pandas/tests/test_series.py
@@ -2814,6 +2814,19 @@ def f(x):
         expected = Series(1,index=range(10),dtype='float64')
         #assert_series_equal(result,expected)
 
+    def test_complexx(self):
+
+        # GH4819
+        # complex access for ndarray compat
+        a = np.arange(5)
+        b = Series(a + 4j*a)
+        tm.assert_almost_equal(a,b.real)
+        tm.assert_almost_equal(4*a,b.imag)
+
+        b.real = np.arange(5)+5
+        tm.assert_almost_equal(a+5,b.real)
+        tm.assert_almost_equal(4*a,b.imag)
+
     def test_underlying_data_conversion(self):
 
         # GH 4080