33"""
44# pylint: disable=E1103,W0231,W0212,W0621
55from __future__ import division
6- from pandas .compat import (map , zip , range , lrange , lmap , u , OrderedDict ,
7- OrderedDefaultdict )
8- from pandas import compat
6+
97import warnings
8+
109import numpy as np
11- from pandas .core .common import (PandasError , _try_sort , _default_index ,
12- _infer_dtype_from_scalar , notnull , is_list_like )
10+
11+ import pandas .computation .expressions as expressions
12+ import pandas .core .common as com
13+ import pandas .core .ops as ops
14+ from pandas import compat
15+ from pandas import lib
16+ from pandas .compat import (map , zip , range , u , OrderedDict ,
17+ OrderedDefaultdict )
1318from pandas .core .categorical import Categorical
19+ from pandas .core .common import (PandasError , _try_sort , _default_index ,
20+ _infer_dtype_from_scalar , is_list_like )
21+ from pandas .core .frame import DataFrame
22+ from pandas .core .generic import NDFrame , _shared_docs
1423from pandas .core .index import (Index , MultiIndex , _ensure_index ,
1524 _get_combined_index )
1625from pandas .core .indexing import maybe_droplevels
1726from pandas .core .internals import (BlockManager ,
1827 create_block_manager_from_arrays ,
1928 create_block_manager_from_blocks )
29+ from pandas .core .ops import _op_descriptions
2030from pandas .core .series import Series
21- from pandas .core .frame import DataFrame
22- from pandas .core .generic import NDFrame , _shared_docs
2331from pandas .tools .util import cartesian_product
24- from pandas import compat
25- from pandas .util .decorators import (deprecate , Appender , Substitution ,
26- deprecate_kwarg )
27- import pandas .core .common as com
28- import pandas .core .ops as ops
29- import pandas .computation .expressions as expressions
30- from pandas import lib
31- from pandas .core .ops import _op_descriptions
32-
32+ from pandas .util .decorators import (deprecate , Appender , deprecate_kwarg )
3333
3434_shared_doc_kwargs = dict (
3535 axes = 'items, major_axis, minor_axis' ,
@@ -105,7 +105,6 @@ def panel_index(time, panels, names=['time', 'panel']):
105105
106106
107107class Panel (NDFrame ):
108-
109108 """
110109 Represents wide format panel data, stored as 3-dimensional array
111110
@@ -149,7 +148,7 @@ def _init_data(self, data, copy, dtype, **kwargs):
149148
150149 if kwargs :
151150 raise TypeError ('_init_data() got an unexpected keyword '
152- 'argument "{0}"' .format (list (kwargs .keys ())[0 ]))
151+ 'argument "{0}"' .format (list (kwargs .keys ())[0 ]))
153152
154153 axes = None
155154 if isinstance (data , BlockManager ):
@@ -307,7 +306,7 @@ def _init_matrix(self, data, axes, dtype=None, copy=False):
307306
308307 return create_block_manager_from_blocks ([values ], fixed_axes )
309308
310- #----------------------------------------------------------------------
309+ # ----------------------------------------------------------------------
311310 # Comparison methods
312311
313312 def _compare_constructor (self , other , func ):
@@ -322,7 +321,7 @@ def _compare_constructor(self, other, func):
322321 d = self ._construct_axes_dict (copy = False )
323322 return self ._constructor (data = new_data , ** d )
324323
325- #----------------------------------------------------------------------
324+ # ----------------------------------------------------------------------
326325 # Magic methods
327326
328327 def __unicode__ (self ):
@@ -378,7 +377,7 @@ def _get_plane_axes(self, axis):
378377 (as compared with higher level planes),
379378 as we are returning a DataFrame axes
380379 """
381- return [ self ._get_axis (axi ) for axi in self ._get_plane_axes_index (axis ) ]
380+ return [self ._get_axis (axi ) for axi in self ._get_plane_axes_index (axis )]
382381
383382 fromDict = from_dict
384383
@@ -458,7 +457,7 @@ def as_matrix(self):
458457 self ._consolidate_inplace ()
459458 return self ._data .as_matrix ()
460459
461- #----------------------------------------------------------------------
460+ # ----------------------------------------------------------------------
462461 # Getting and setting elements
463462
464463 def get_value (self , * args , ** kwargs ):
@@ -488,7 +487,7 @@ def get_value(self, *args, **kwargs):
488487
489488 if kwargs :
490489 raise TypeError ('get_value() got an unexpected keyword '
491- 'argument "{0}"' .format (list (kwargs .keys ())[0 ]))
490+ 'argument "{0}"' .format (list (kwargs .keys ())[0 ]))
492491
493492 if takeable is True :
494493 lower = self ._iget_item_cache (args [0 ])
@@ -527,7 +526,7 @@ def set_value(self, *args, **kwargs):
527526
528527 if kwargs :
529528 raise TypeError ('set_value() got an unexpected keyword '
530- 'argument "{0}"' .format (list (kwargs .keys ())[0 ]))
529+ 'argument "{0}"' .format (list (kwargs .keys ())[0 ]))
531530
532531 try :
533532 if takeable is True :
@@ -681,8 +680,8 @@ def _combine(self, other, func, axis=0):
681680 return self ._combine_const (other , func )
682681 else :
683682 raise NotImplementedError (str (type (other )) +
684- ' is not supported in combine operation with ' +
685- str (type (self )))
683+ ' is not supported in combine operation with ' +
684+ str (type (self )))
686685
687686 def _combine_const (self , other , func ):
688687 new_values = func (self .values , other )
@@ -944,27 +943,41 @@ def construct_index_parts(idx, major=True):
944943
945944 def apply (self , func , axis = 'major' , ** kwargs ):
946945 """
947- Applies function along input axis of the Panel
946+ Applies function along axis (or axes) of the Panel
948947
949948 Parameters
950949 ----------
951950 func : function
952951 Function to apply to each combination of 'other' axes
953- e.g. if axis = 'items', then the combination of major_axis/minor_axis
954- will be passed a Series
955- axis : {'major', 'minor', 'items'}
952+ e.g. if axis = 'items', the combination of major_axis/minor_axis
953+ will each be passed as a Series; if axis = ('items', 'major'), DataFrames
954+ of items & major axis will be passed
955+ axis : {'items', 'minor', 'major'}, or {0, 1, 2}, or a tuple with two axes
956956 Additional keyword arguments will be passed as keywords to the function
957957
958958 Examples
959959 --------
960- >>> p.apply(numpy.sqrt) # returns a Panel
961- >>> p.apply(lambda x: x.sum(), axis=0) # equiv to p.sum(0)
962- >>> p.apply(lambda x: x.sum(), axis=1) # equiv to p.sum(1)
963- >>> p.apply(lambda x: x.sum(), axis=2) # equiv to p.sum(2)
960+
961+ Returns a Panel with the square root of each element
962+
963+ >>> p = pd.Panel(np.random.rand(4,3,2))
964+ >>> p.apply(np.sqrt)
965+
966+ Equivalent to p.sum(1), returning a DataFrame
967+
968+ >>> p.apply(lambda x: x.sum(), axis=1)
969+
970+ Equivalent to previous:
971+
972+ >>> p.apply(lambda x: x.sum(), axis='minor')
973+
974+ Return the shapes of each DataFrame over axis 2 (i.e the shapes of items x major), as a Series
975+
976+ >>> p.apply(lambda x: x.shape, axis=(0,1))
964977
965978 Returns
966979 -------
967- result : Pandas Object
980+ result : Panel, DataFrame, or Series
968981 """
969982
970983 if kwargs and not isinstance (func , np .ufunc ):
@@ -973,7 +986,7 @@ def apply(self, func, axis='major', **kwargs):
973986 f = func
974987
975988 # 2d-slabs
976- if isinstance (axis , (tuple ,list )) and len (axis ) == 2 :
989+ if isinstance (axis , (tuple , list )) and len (axis ) == 2 :
977990 return self ._apply_2d (f , axis = axis )
978991
979992 axis = self ._get_axis_number (axis )
@@ -998,13 +1011,13 @@ def _apply_1d(self, func, axis):
9981011
9991012 # iter thru the axes
10001013 slice_axis = self ._get_axis (axis )
1001- slice_indexer = [0 ]* (ndim - 1 )
1014+ slice_indexer = [0 ] * (ndim - 1 )
10021015 indexer = np .zeros (ndim , 'O' )
10031016 indlist = list (range (ndim ))
10041017 indlist .remove (axis )
10051018 indexer [axis ] = slice (None , None )
10061019 indexer .put (indlist , slice_indexer )
1007- planes = [ self ._get_axis (axi ) for axi in indlist ]
1020+ planes = [self ._get_axis (axi ) for axi in indlist ]
10081021 shape = np .array (self .shape ).take (indlist )
10091022
10101023 # all the iteration points
@@ -1014,19 +1027,19 @@ def _apply_1d(self, func, axis):
10141027 for i in range (np .prod (shape )):
10151028
10161029 # construct the object
1017- pts = tuple ([ p [i ] for p in points ])
1030+ pts = tuple ([p [i ] for p in points ])
10181031 indexer .put (indlist , slice_indexer )
10191032
1020- obj = Series (values [tuple (indexer )],index = slice_axis ,name = pts )
1033+ obj = Series (values [tuple (indexer )], index = slice_axis , name = pts )
10211034 result = func (obj )
10221035
10231036 results .append (result )
10241037
10251038 # increment the indexer
10261039 slice_indexer [- 1 ] += 1
10271040 n = - 1
1028- while (slice_indexer [n ] >= shape [n ]) and (n > (1 - ndim )):
1029- slice_indexer [n - 1 ] += 1
1041+ while (slice_indexer [n ] >= shape [n ]) and (n > (1 - ndim )):
1042+ slice_indexer [n - 1 ] += 1
10301043 slice_indexer [n ] = 0
10311044 n -= 1
10321045
@@ -1035,43 +1048,42 @@ def _apply_1d(self, func, axis):
10351048 return self ._constructor (** self ._construct_axes_dict ())
10361049
10371050 # same ndim as current
1038- if isinstance (results [0 ],Series ):
1039- arr = np .vstack ([ r .values for r in results ])
1051+ if isinstance (results [0 ], Series ):
1052+ arr = np .vstack ([r .values for r in results ])
10401053 arr = arr .T .reshape (tuple ([len (slice_axis )] + list (shape )))
1041- tranp = np .array ([axis ]+ indlist ).argsort ()
1054+ tranp = np .array ([axis ] + indlist ).argsort ()
10421055 arr = arr .transpose (tuple (list (tranp )))
1043- return self ._constructor (arr ,** self ._construct_axes_dict ())
1056+ return self ._constructor (arr , ** self ._construct_axes_dict ())
10441057
10451058 # ndim-1 shape
10461059 results = np .array (results ).reshape (shape )
10471060 if results .ndim == 2 and axis_name != self ._info_axis_name :
10481061 results = results .T
10491062 planes = planes [::- 1 ]
1050- return self ._construct_return_type (results ,planes )
1063+ return self ._construct_return_type (results , planes )
10511064
10521065 def _apply_2d (self , func , axis ):
10531066 """ handle 2-d slices, equiv to iterating over the other axis """
10541067
10551068 ndim = self .ndim
1056- axis = [ self ._get_axis_number (a ) for a in axis ]
1069+ axis = [self ._get_axis_number (a ) for a in axis ]
10571070
10581071 # construct slabs, in 2-d this is a DataFrame result
10591072 indexer_axis = list (range (ndim ))
10601073 for a in axis :
10611074 indexer_axis .remove (a )
10621075 indexer_axis = indexer_axis [0 ]
10631076
1064- slicer = [ slice (None ,None ) ] * ndim
1077+ slicer = [slice (None , None )] * ndim
10651078 ax = self ._get_axis (indexer_axis )
10661079
10671080 results = []
10681081 for i , e in enumerate (ax ):
1069-
10701082 slicer [indexer_axis ] = i
10711083 sliced = self .iloc [tuple (slicer )]
10721084
10731085 obj = func (sliced )
1074- results .append ((e ,obj ))
1086+ results .append ((e , obj ))
10751087
10761088 return self ._construct_return_type (dict (results ))
10771089
@@ -1095,12 +1107,12 @@ def _reduce(self, op, name, axis=0, skipna=True, numeric_only=None,
10951107
10961108 def _construct_return_type (self , result , axes = None ):
10971109 """ return the type for the ndim of the result """
1098- ndim = getattr (result ,'ndim' ,None )
1110+ ndim = getattr (result , 'ndim' , None )
10991111
11001112 # need to assume they are the same
11011113 if ndim is None :
1102- if isinstance (result ,dict ):
1103- ndim = getattr (list (compat .itervalues (result ))[0 ],'ndim' ,0 )
1114+ if isinstance (result , dict ):
1115+ ndim = getattr (list (compat .itervalues (result ))[0 ], 'ndim' , 0 )
11041116
11051117 # have a dict, so top-level is +1 dim
11061118 if ndim != 0 :
@@ -1189,7 +1201,7 @@ def count(self, axis='major'):
11891201
11901202 values = self .values
11911203 mask = np .isfinite (values )
1192- result = mask .sum (axis = i ,dtype = 'int64' )
1204+ result = mask .sum (axis = i , dtype = 'int64' )
11931205
11941206 return self ._wrap_result (result , axis )
11951207
@@ -1496,6 +1508,7 @@ def na_op(x, y):
14961508 @Appender (doc )
14971509 def f (self , other , axis = 0 ):
14981510 return self ._combine (other , na_op , axis = axis )
1511+
14991512 f .__name__ = name
15001513 return f
15011514
@@ -1504,6 +1517,7 @@ def f(self, other, axis=0):
15041517 cls , _panel_arith_method , use_numexpr = use_numexpr ,
15051518 flex_comp_method = ops ._comp_method_PANEL )
15061519
1520+
15071521Panel ._setup_axes (axes = ['items' , 'major_axis' , 'minor_axis' ],
15081522 info_axis = 0 ,
15091523 stat_axis = 1 ,
@@ -1516,21 +1530,19 @@ def f(self, other, axis=0):
15161530Panel ._add_aggregate_operations ()
15171531Panel ._add_numeric_operations ()
15181532
1533+
15191534# legacy
15201535class WidePanel (Panel ):
1521-
15221536 def __init__ (self , * args , ** kwargs ):
1523-
15241537 # deprecation, #10892
15251538 warnings .warn ("WidePanel is deprecated. Please use Panel" ,
15261539 FutureWarning , stacklevel = 2 )
15271540
15281541 super (WidePanel , self ).__init__ (* args , ** kwargs )
15291542
1530- class LongPanel (DataFrame ):
15311543
1544+ class LongPanel (DataFrame ):
15321545 def __init__ (self , * args , ** kwargs ):
1533-
15341546 # deprecation, #10892
15351547 warnings .warn ("LongPanel is deprecated. Please use DataFrame" ,
15361548 FutureWarning , stacklevel = 2 )
0 commit comments