@@ -1372,6 +1372,7 @@ def _join_multi(self, other, how, return_indexers=True):
1372
1372
raise ValueError ("cannot join with no level specified and no overlapping names" )
1373
1373
if len (overlap ) > 1 :
1374
1374
raise NotImplementedError ("merging with more than one level overlap on a multi-index is not implemented" )
1375
+
1375
1376
jl = overlap [0 ]
1376
1377
1377
1378
# make the indices into mi's that match
@@ -1392,7 +1393,74 @@ def _join_multi(self, other, how, return_indexers=True):
1392
1393
return result
1393
1394
1394
1395
# 2 multi-indexes
1395
- raise NotImplementedError ("merging with both multi-indexes is not implemented" )
1396
+ left_values = other .get_level_values (jl )
1397
+ left_joined , left_lidx , left_ridx = self ._join_level (left_values , jl , how = how ,
1398
+ return_indexers = True )
1399
+ right_values = self .get_level_values (jl )
1400
+ right_joined , right_lidx , right_ridx = other ._join_level (right_values , jl , how = how ,
1401
+ return_indexers = True )
1402
+
1403
+ # new levels
1404
+ levels = list (left_joined .levels )
1405
+ levels_names = set ([ l .name for l in levels ])
1406
+ levels += [ l for l in right_joined .levels if l .name not in levels_names ]
1407
+
1408
+ # number of reps of labels
1409
+ l = len (left_joined )* len (right_joined )
1410
+
1411
+ # new labels
1412
+ lidx = com ._ensure_int64 (left_lidx )
1413
+ ridx = com ._ensure_int64 (right_lidx )
1414
+ labels = []
1415
+ indexers = []
1416
+
1417
+ def _get_labels (joined , name , indexer ):
1418
+ ln = joined ._get_level_number (name )
1419
+ lev_labels = np .tile (joined .labels [ln ],l / len (joined .labels [ln ]))
1420
+ rev_indexer = lib .get_reverse_indexer (indexer ,l )
1421
+ new_labels = com .take_nd (rev_indexer , lev_labels ,
1422
+ allow_fill = False )
1423
+ omit_mask = new_labels != - 1
1424
+ new_indexer = np .arange (len (lev_labels ))[omit_mask ]
1425
+
1426
+ return new_labels , new_indexer
1427
+
1428
+ for level in levels :
1429
+
1430
+ name = level .name
1431
+
1432
+ in_left = name in left_joined .names
1433
+ in_right = name in right_joined .names
1434
+
1435
+ if not in_left and in_right :
1436
+ new_labels , new_indexer = _get_labels (right_joined , name , ridx )
1437
+ else :
1438
+ # left or the joined
1439
+ new_labels , new_indexer = _get_labels (left_joined , name , lidx )
1440
+
1441
+ labels .append (new_labels )
1442
+ indexers .append (new_indexer )
1443
+
1444
+ import pdb ; pdb .set_trace ()
1445
+
1446
+ return MultiIndex (labels = labels ,levels = levels ), left_lidx , right_ridx
1447
+
1448
+ #sjl = self._get_level_number(jl)
1449
+ #left_indexer = np.array(sorted(list(set(np.arange(len(self.levels)))-set([sjl]))))
1450
+ #ojl = other._get_level_number(jl)
1451
+ #right_indexer = np.array(sorted(list(set(np.arange(len(other.levels)))-set([ojl]))))
1452
+
1453
+ #tuples = []
1454
+ #for left, right in zip(self.take(lidx).values, other.take(ridx).values):
1455
+ # def _create_tuple(left, right, i):
1456
+ # t = []
1457
+ # t.extend(list(np.array(left).take(left_indexer)))
1458
+ # t.append(left[i])
1459
+ # t.extend(list(np.array(right).take(right_indexer)))
1460
+ # return tuple(t)
1461
+
1462
+ #tuples = [ _create_tuple(left, right, sjl)
1463
+ #return MultiIndex.from_tuples(tuples,names=_create_tuple(self.names,other.names,sjl)), lidx, ridx
1396
1464
1397
1465
def _join_non_unique (self , other , how = 'left' , return_indexers = False ):
1398
1466
from pandas .tools .merge import _get_join_indexers
0 commit comments