8
8
from pandas .core .common import (adjoin as _adjoin , _stringify ,
9
9
_is_bool_indexer , _asarray_tuplesafe )
10
10
from pandas .util .decorators import cache_readonly
11
+ import pandas .core .common as com
11
12
import pandas ._tseries as lib
12
13
import pandas ._engines as _engines
13
14
@@ -868,27 +869,32 @@ def __new__(cls, levels=None, labels=None, sortorder=None, names=None):
868
869
869
870
return Index (levels [0 ], name = name ).take (labels [0 ])
870
871
871
- return np .arange (len (labels [0 ]), dtype = object ).view (cls )
872
+ levels = [_ensure_index (lev ) for lev in levels ]
873
+ labels = [np .asarray (labs , dtype = np .int32 ) for labs in labels ]
872
874
873
- def __init__ (self , levels , labels , sortorder = None , names = None ,
874
- consistent = None ):
875
- self .levels = [_ensure_index (lev ) for lev in levels ]
876
- self .labels = [np .asarray (labs , dtype = np .int32 ) for labs in labels ]
875
+ values = [np .asarray (lev ).take (lab )
876
+ for lev , lab in zip (levels , labels )]
877
+ subarr = lib .fast_zip (values ).view (cls )
878
+
879
+ subarr .levels = levels
880
+ subarr .labels = labels
877
881
878
882
if names is None :
879
- self .names = [None ] * self .nlevels
883
+ subarr .names = [None ] * subarr .nlevels
880
884
else :
881
- assert (len (names ) == self .nlevels )
882
- self .names = list (names )
885
+ assert (len (names ) == subarr .nlevels )
886
+ subarr .names = list (names )
883
887
884
888
# set the name
885
- for i , name in enumerate (self .names ):
886
- self .levels [i ].name = name
889
+ for i , name in enumerate (subarr .names ):
890
+ subarr .levels [i ].name = name
887
891
888
892
if sortorder is not None :
889
- self .sortorder = int (sortorder )
893
+ subarr .sortorder = int (sortorder )
890
894
else :
891
- self .sortorder = sortorder
895
+ subarr .sortorder = sortorder
896
+
897
+ return subarr
892
898
893
899
@property
894
900
def dtype (self ):
@@ -908,9 +914,18 @@ def _get_level_number(self, level):
908
914
909
915
@property
910
916
def values (self ):
911
- values = [np .asarray (lev ).take (lab )
912
- for lev , lab in zip (self .levels , self .labels )]
913
- return lib .fast_zip (values )
917
+ if self ._is_legacy_format :
918
+ # for legacy MultiIndex
919
+ values = [np .asarray (lev ).take (lab )
920
+ for lev , lab in zip (self .levels , self .labels )]
921
+ return lib .fast_zip (values )
922
+ else :
923
+ return self .view (np .ndarray )
924
+
925
+ @property
926
+ def _is_legacy_format (self ):
927
+ contents = self .view (np .ndarray )
928
+ return len (contents ) > 0 and not isinstance (contents [0 ], tuple )
914
929
915
930
def get_level_values (self , level ):
916
931
"""
@@ -1112,7 +1127,7 @@ def append(self, other):
1112
1127
return MultiIndex .from_tuples (new_tuples , names = self .names )
1113
1128
1114
1129
def argsort (self , * args , ** kwargs ):
1115
- return self .get_tuple_index () .argsort ()
1130
+ return self .values .argsort ()
1116
1131
1117
1132
def drop (self , labels ):
1118
1133
"""
@@ -1290,10 +1305,12 @@ def get_indexer(self, target, method=None):
1290
1305
method = self ._get_method (method )
1291
1306
1292
1307
target_index = target
1293
- if isinstance (target , MultiIndex ):
1308
+ if isinstance (target , MultiIndex ) and target . _is_legacy_format :
1294
1309
target_index = target .get_tuple_index ()
1295
1310
1296
- self_index = self .get_tuple_index ()
1311
+ self_index = self
1312
+ if self ._is_legacy_format :
1313
+ self_index = self .get_tuple_index ()
1297
1314
1298
1315
if method == 'pad' :
1299
1316
indexer = self ._pad (self_index , target_index , self_index .indexMap ,
@@ -1332,7 +1349,7 @@ def get_tuple_index(self):
1332
1349
-------
1333
1350
index : Index
1334
1351
"""
1335
- return Index (list ( self ) )
1352
+ return Index (self . values )
1336
1353
1337
1354
def slice_locs (self , start = None , end = None , strict = False ):
1338
1355
"""
0 commit comments