3
3
"""
4
4
# pylint: disable=E1103,W0231,W0212,W0621
5
5
from __future__ import division
6
- from pandas .compat import (map , zip , range , lrange , lmap , u , OrderedDict ,
7
- OrderedDefaultdict )
8
- from pandas import compat
6
+
9
7
import warnings
8
+
10
9
import 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 )
13
18
from 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
14
23
from pandas .core .index import (Index , MultiIndex , _ensure_index ,
15
24
_get_combined_index )
16
25
from pandas .core .indexing import maybe_droplevels
17
26
from pandas .core .internals import (BlockManager ,
18
27
create_block_manager_from_arrays ,
19
28
create_block_manager_from_blocks )
29
+ from pandas .core .ops import _op_descriptions
20
30
from pandas .core .series import Series
21
- from pandas .core .frame import DataFrame
22
- from pandas .core .generic import NDFrame , _shared_docs
23
31
from 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 )
33
33
34
34
_shared_doc_kwargs = dict (
35
35
axes = 'items, major_axis, minor_axis' ,
@@ -105,7 +105,6 @@ def panel_index(time, panels, names=['time', 'panel']):
105
105
106
106
107
107
class Panel (NDFrame ):
108
-
109
108
"""
110
109
Represents wide format panel data, stored as 3-dimensional array
111
110
@@ -149,7 +148,7 @@ def _init_data(self, data, copy, dtype, **kwargs):
149
148
150
149
if kwargs :
151
150
raise TypeError ('_init_data() got an unexpected keyword '
152
- 'argument "{0}"' .format (list (kwargs .keys ())[0 ]))
151
+ 'argument "{0}"' .format (list (kwargs .keys ())[0 ]))
153
152
154
153
axes = None
155
154
if isinstance (data , BlockManager ):
@@ -307,7 +306,7 @@ def _init_matrix(self, data, axes, dtype=None, copy=False):
307
306
308
307
return create_block_manager_from_blocks ([values ], fixed_axes )
309
308
310
- #----------------------------------------------------------------------
309
+ # ----------------------------------------------------------------------
311
310
# Comparison methods
312
311
313
312
def _compare_constructor (self , other , func ):
@@ -322,7 +321,7 @@ def _compare_constructor(self, other, func):
322
321
d = self ._construct_axes_dict (copy = False )
323
322
return self ._constructor (data = new_data , ** d )
324
323
325
- #----------------------------------------------------------------------
324
+ # ----------------------------------------------------------------------
326
325
# Magic methods
327
326
328
327
def __unicode__ (self ):
@@ -378,7 +377,7 @@ def _get_plane_axes(self, axis):
378
377
(as compared with higher level planes),
379
378
as we are returning a DataFrame axes
380
379
"""
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 )]
382
381
383
382
fromDict = from_dict
384
383
@@ -458,7 +457,7 @@ def as_matrix(self):
458
457
self ._consolidate_inplace ()
459
458
return self ._data .as_matrix ()
460
459
461
- #----------------------------------------------------------------------
460
+ # ----------------------------------------------------------------------
462
461
# Getting and setting elements
463
462
464
463
def get_value (self , * args , ** kwargs ):
@@ -488,7 +487,7 @@ def get_value(self, *args, **kwargs):
488
487
489
488
if kwargs :
490
489
raise TypeError ('get_value() got an unexpected keyword '
491
- 'argument "{0}"' .format (list (kwargs .keys ())[0 ]))
490
+ 'argument "{0}"' .format (list (kwargs .keys ())[0 ]))
492
491
493
492
if takeable is True :
494
493
lower = self ._iget_item_cache (args [0 ])
@@ -527,7 +526,7 @@ def set_value(self, *args, **kwargs):
527
526
528
527
if kwargs :
529
528
raise TypeError ('set_value() got an unexpected keyword '
530
- 'argument "{0}"' .format (list (kwargs .keys ())[0 ]))
529
+ 'argument "{0}"' .format (list (kwargs .keys ())[0 ]))
531
530
532
531
try :
533
532
if takeable is True :
@@ -681,8 +680,8 @@ def _combine(self, other, func, axis=0):
681
680
return self ._combine_const (other , func )
682
681
else :
683
682
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 )))
686
685
687
686
def _combine_const (self , other , func ):
688
687
new_values = func (self .values , other )
@@ -944,27 +943,41 @@ def construct_index_parts(idx, major=True):
944
943
945
944
def apply (self , func , axis = 'major' , ** kwargs ):
946
945
"""
947
- Applies function along input axis of the Panel
946
+ Applies function along axis (or axes) of the Panel
948
947
949
948
Parameters
950
949
----------
951
950
func : function
952
951
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
956
956
Additional keyword arguments will be passed as keywords to the function
957
957
958
958
Examples
959
959
--------
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))
964
977
965
978
Returns
966
979
-------
967
- result : Pandas Object
980
+ result : Panel, DataFrame, or Series
968
981
"""
969
982
970
983
if kwargs and not isinstance (func , np .ufunc ):
@@ -973,7 +986,7 @@ def apply(self, func, axis='major', **kwargs):
973
986
f = func
974
987
975
988
# 2d-slabs
976
- if isinstance (axis , (tuple ,list )) and len (axis ) == 2 :
989
+ if isinstance (axis , (tuple , list )) and len (axis ) == 2 :
977
990
return self ._apply_2d (f , axis = axis )
978
991
979
992
axis = self ._get_axis_number (axis )
@@ -998,13 +1011,13 @@ def _apply_1d(self, func, axis):
998
1011
999
1012
# iter thru the axes
1000
1013
slice_axis = self ._get_axis (axis )
1001
- slice_indexer = [0 ]* (ndim - 1 )
1014
+ slice_indexer = [0 ] * (ndim - 1 )
1002
1015
indexer = np .zeros (ndim , 'O' )
1003
1016
indlist = list (range (ndim ))
1004
1017
indlist .remove (axis )
1005
1018
indexer [axis ] = slice (None , None )
1006
1019
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 ]
1008
1021
shape = np .array (self .shape ).take (indlist )
1009
1022
1010
1023
# all the iteration points
@@ -1014,19 +1027,19 @@ def _apply_1d(self, func, axis):
1014
1027
for i in range (np .prod (shape )):
1015
1028
1016
1029
# construct the object
1017
- pts = tuple ([ p [i ] for p in points ])
1030
+ pts = tuple ([p [i ] for p in points ])
1018
1031
indexer .put (indlist , slice_indexer )
1019
1032
1020
- obj = Series (values [tuple (indexer )],index = slice_axis ,name = pts )
1033
+ obj = Series (values [tuple (indexer )], index = slice_axis , name = pts )
1021
1034
result = func (obj )
1022
1035
1023
1036
results .append (result )
1024
1037
1025
1038
# increment the indexer
1026
1039
slice_indexer [- 1 ] += 1
1027
1040
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
1030
1043
slice_indexer [n ] = 0
1031
1044
n -= 1
1032
1045
@@ -1035,43 +1048,42 @@ def _apply_1d(self, func, axis):
1035
1048
return self ._constructor (** self ._construct_axes_dict ())
1036
1049
1037
1050
# 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 ])
1040
1053
arr = arr .T .reshape (tuple ([len (slice_axis )] + list (shape )))
1041
- tranp = np .array ([axis ]+ indlist ).argsort ()
1054
+ tranp = np .array ([axis ] + indlist ).argsort ()
1042
1055
arr = arr .transpose (tuple (list (tranp )))
1043
- return self ._constructor (arr ,** self ._construct_axes_dict ())
1056
+ return self ._constructor (arr , ** self ._construct_axes_dict ())
1044
1057
1045
1058
# ndim-1 shape
1046
1059
results = np .array (results ).reshape (shape )
1047
1060
if results .ndim == 2 and axis_name != self ._info_axis_name :
1048
1061
results = results .T
1049
1062
planes = planes [::- 1 ]
1050
- return self ._construct_return_type (results ,planes )
1063
+ return self ._construct_return_type (results , planes )
1051
1064
1052
1065
def _apply_2d (self , func , axis ):
1053
1066
""" handle 2-d slices, equiv to iterating over the other axis """
1054
1067
1055
1068
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 ]
1057
1070
1058
1071
# construct slabs, in 2-d this is a DataFrame result
1059
1072
indexer_axis = list (range (ndim ))
1060
1073
for a in axis :
1061
1074
indexer_axis .remove (a )
1062
1075
indexer_axis = indexer_axis [0 ]
1063
1076
1064
- slicer = [ slice (None ,None ) ] * ndim
1077
+ slicer = [slice (None , None )] * ndim
1065
1078
ax = self ._get_axis (indexer_axis )
1066
1079
1067
1080
results = []
1068
1081
for i , e in enumerate (ax ):
1069
-
1070
1082
slicer [indexer_axis ] = i
1071
1083
sliced = self .iloc [tuple (slicer )]
1072
1084
1073
1085
obj = func (sliced )
1074
- results .append ((e ,obj ))
1086
+ results .append ((e , obj ))
1075
1087
1076
1088
return self ._construct_return_type (dict (results ))
1077
1089
@@ -1095,12 +1107,12 @@ def _reduce(self, op, name, axis=0, skipna=True, numeric_only=None,
1095
1107
1096
1108
def _construct_return_type (self , result , axes = None ):
1097
1109
""" return the type for the ndim of the result """
1098
- ndim = getattr (result ,'ndim' ,None )
1110
+ ndim = getattr (result , 'ndim' , None )
1099
1111
1100
1112
# need to assume they are the same
1101
1113
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 )
1104
1116
1105
1117
# have a dict, so top-level is +1 dim
1106
1118
if ndim != 0 :
@@ -1189,7 +1201,7 @@ def count(self, axis='major'):
1189
1201
1190
1202
values = self .values
1191
1203
mask = np .isfinite (values )
1192
- result = mask .sum (axis = i ,dtype = 'int64' )
1204
+ result = mask .sum (axis = i , dtype = 'int64' )
1193
1205
1194
1206
return self ._wrap_result (result , axis )
1195
1207
@@ -1496,6 +1508,7 @@ def na_op(x, y):
1496
1508
@Appender (doc )
1497
1509
def f (self , other , axis = 0 ):
1498
1510
return self ._combine (other , na_op , axis = axis )
1511
+
1499
1512
f .__name__ = name
1500
1513
return f
1501
1514
@@ -1504,6 +1517,7 @@ def f(self, other, axis=0):
1504
1517
cls , _panel_arith_method , use_numexpr = use_numexpr ,
1505
1518
flex_comp_method = ops ._comp_method_PANEL )
1506
1519
1520
+
1507
1521
Panel ._setup_axes (axes = ['items' , 'major_axis' , 'minor_axis' ],
1508
1522
info_axis = 0 ,
1509
1523
stat_axis = 1 ,
@@ -1516,21 +1530,19 @@ def f(self, other, axis=0):
1516
1530
Panel ._add_aggregate_operations ()
1517
1531
Panel ._add_numeric_operations ()
1518
1532
1533
+
1519
1534
# legacy
1520
1535
class WidePanel (Panel ):
1521
-
1522
1536
def __init__ (self , * args , ** kwargs ):
1523
-
1524
1537
# deprecation, #10892
1525
1538
warnings .warn ("WidePanel is deprecated. Please use Panel" ,
1526
1539
FutureWarning , stacklevel = 2 )
1527
1540
1528
1541
super (WidePanel , self ).__init__ (* args , ** kwargs )
1529
1542
1530
- class LongPanel (DataFrame ):
1531
1543
1544
+ class LongPanel (DataFrame ):
1532
1545
def __init__ (self , * args , ** kwargs ):
1533
-
1534
1546
# deprecation, #10892
1535
1547
warnings .warn ("LongPanel is deprecated. Please use DataFrame" ,
1536
1548
FutureWarning , stacklevel = 2 )
0 commit comments