pydata/pandas — pull request #3482 by jreback (2013-04-29 14:37:35+00:00)
Title: CLN: series to now inherit from NDFrame

Major refactor primarily to make Series inherit from NDFrame
Preserves pickle compat
very few tests were changed (and only for compat on return objects)
a few performance enhancements, a couple of regressions (see bottom)

*obviously this is a large change in terms of the codebase, but it brings more consistency between series/frame/panel (not all of this is there yet, but future changes are much easier)*

*Series is now like Frame in that it has a BlockManager (called SingleBlockManager), which holds a block (of any type we support). This introduced some overhead in doing certain operations, which I spent a lot of time optimizing away, further optimizations will come from cythonizing the core/internals, which should be straightforward at this point*

Highlites below:

- Refactor of PandasObject to become new generic Pandas base class
- moved methods
- __str__,__bytes__,__repr__,save,load
- affects all NDFrame hierarchy, Index hierarchy, Period (Timestamp not included)

- Refactor of series.py/frame.py/panel.py to move common code to generic.py
- added _setup_axes to created generic NDFrame structures
- moved methods

- from_axes,_wrap_array,axes,ix,shape,empty,swapaxes,transpose,pop
- __iter__,keys,__contains__,__len__,__neg__,__invert__
- convert_objects,as_blocks,as_matrix,values
- __getstate__,__setstate__ (though compat remains in frame/panel)
- __getattr__,__setattr__
- _indexed_same,reindex_like,reindex,align,where,mask
- filter (also added axis argument to selectively filter on a different axis)
- reindex,reindex_axis (which was the biggest change to make generic)
- truncate (moved to become part of NDFrame)

These are API changes which make Panel more consistent with DataFrame
- swapaxes on a Panel with the same axes specified now return a copy
- support attribute access for setting
- filter supports same api as original DataFrame filter

- Reindex called with no arguments will now return a copy of the input object

- Series now inherits from ``NDFrame`` rather than directly from ``ndarray``.
There are several minor changes that affect the API.

- numpy functions that do not support the array interface will now
return ``ndarrays`` rather than series, e.g. ``np.diff`` and ``np.where``
- ``Series(0.5)`` would previously return the scalar ``0.5``, this is not
longer supported
- several methods from frame/series have moved to ``NDFrame``
(convert_objects,where,mask)
- ``TimeSeries`` is now an alias for ``Series``. the property ``is_time_series``
can be used to distinguish (if desired)

- Refactor of Sparse objects to use BlockManager

- Created a new block type in internals, SparseBlock, which can hold multi-dtypes
and is non-consolidatable. SparseSeries and SparseDataFrame now inherit
more methods from there hierarchy (Series/DataFrame), and no longer inherit
from SparseArray (which instead is the object of the SparseBlock)
- Sparse suite now supports integration with non-sparse data. Non-float sparse
data is supportable (partially implemented)
- Operations on sparse structures within DataFrames should preserve sparseness,
merging type operations will convert to dense (and back to sparse), so might
be somewhat inefficient
- enable setitem on SparseSeries for boolean/integer/slices
- SparsePanels implementation is unchanged (e.g. not using BlockManager, needs work)

- added ``ftypes`` method to Series/DataFame, similar to ``dtypes``, but indicates
if the underlying is sparse/dense (as well as the dtype)

Perf changed a bit primarily in groupby where a Series has to be reconstructed in order to be passed to the function (in some cases). the biggest regression is actually a special case and can trivially be changed to be MUCH faster (as this requires a Series for a sum operation), in any event the cython versions are quite fast.

```
-------------------------------------------------------------------------------
Test name | head[ms] | base[ms] | ratio |
-------------------------------------------------------------------------------
frame_reindex_both_axes | 18.8640 | 36.5677 | 0.5159 |
frame_reindex_both_axes_ix | 18.7081 | 35.0070 | 0.5344 |
groupby_apply_dict_return | 31.2620 | 43.8453 | 0.7130 |
indexing_panel_subset | 0.4027 | 0.5000 | 0.8053 |
series_constructor_ndarray | 0.0173 | 0.0113 | 1.5352 |
frame_iteritems | 3.4393 | 1.8907 | 1.8191 |
frame_fancy_lookup | 3.4020 | 1.4997 | 2.2685 |
sparse_frame_constructor | 12.0993 | 4.8280 | 2.5061 |
groupby_multi_python | 204.1063 | 44.7550 | 4.5605 |
-------------------------------------------------------------------------------
Test name | head[ms] | base[ms] | ratio |
-------------------------------------------------------------------------------

Target [dfb119d] : PERF: made constructions of SparseFrame have less redundant steps
Base [67ad556] : Merge pull request #3459 from jreback/GH3455