2016-05-21 2 views
2

Учитывая следующие таблицы из CSV-файлов:Панды Слияние SingleIndex в мультииндексных из CSV

CSV 1:

A B    C 
    AA BB1  BB2  CC 
0 1 text 5  7 
1 2 text2 6  8 
2 3 text3 7  9 

в панд:

import pandas as pd 
mi=pd.read_csv('csv_to_mi.csv',header=[0,1],encoding='latin-1') 
mi = mi.rename(columns={'Unnamed: 2_level_0':'B'}) 
mi 

    A B    C 
    AA BB1  BB2 CC 
0 1 text  5  7 
1 2 text2 6  8 
2 3 text3 7  9 

CSV 2:

A  D E 
    text T1 9 
    text2 T2 10 
    text3 T3 11 

in Pandas:

si=pd.read_csv('csv_to_si.csv',encoding='latin-1') 
si 

    A  D E 
0 text T1 9 
1 text2 T2 10 
2 text3 T3 11 

Я хочу, чтобы объединить их на m1 [ 'B', 'ВВ1'] и s1 [ 'A'], чтобы получить это (или функциональный мульти-индексируется кадра данных):

A B    C D E 
    AA BB1  BB2 CC 
0 1 text  5  7 T1 9 
1 2 text2 6  8 T2 10 
2 3 text3 7  9 T3 11 

Я сделал что-то подобное раньше, и, похоже, все получилось хорошо, за исключением случаев, когда я попытался переименовать 2 столбца в фрейм данных слияния, и по какой-то причине он сбросил все остальные (не переименованные) столбцы. Я также пробовал прочитать мультииндексированный csv только с верхней строкой заголовка (как с одним индексом), слияние двух вместе, а затем сделать результат с несколькими индексами. Кажется, это работало, пока я не столкнулся с проблемой переименования.

Я попытался преобразовать одноиндексный фрейм данных в мультииндексированный фрейм данных сначала, per jezrael's sage advice (который работал хорошо), а затем объединился с мультииндексированным, но это тоже не сработало.

Заранее благодарен!

+0

Под столбцами первого уровня 'D' и' E' могут быть 'CC' и 'CC'? – jezrael

+0

К сожалению нет. Но они могут быть чем угодно (даже цифры, согласно вашему предыдущему решению, связанному с этим сообщением). –

ответ

2

Вы можете использовать merge с drop колонке ('A', 0):

cols = list(zip(si.columns, range(si.shape[1]))) 
si.columns = pd.MultiIndex.from_tuples(cols) 
print (si) 
     A D E 
     0 1 2 
0 text T1 9 
1 text2 T2 10 
2 text3 T3 11 

print (pd.merge(mi,si, left_on=[('B','BB1')], right_on=[('A', 0)]).drop([('A', 0)], axis=1)) 
    A  B  C D E 
    AA BB1 BB2 CC 1 2 
0 1 text 5 7 T1 9 
1 2 text2 6 8 T2 10 
2 3 text3 7 9 T3 11 

отредактировать комментарий - используйте get_level_values:

print (df) 
    A  B  C D E 
    AA BB1 BB2 CC 1 2 
0 1 text 5 7 T1 9 
1 2 text2 6 8 T2 10 
2 3 text3 7 9 T3 11 

print (df.columns.get_level_values(0)) 
Index(['A', 'B', 'B', 'C', 'D', 'E'], dtype='object') 

cols = list(zip(df.columns.get_level_values(0), df.columns.get_level_values(0))) 
df.columns = pd.MultiIndex.from_tuples(cols) 
print (df) 
    A  B  C D E 
    A  B B C D E 
0 1 text 5 7 T1 9 
1 2 text2 6 8 T2 10 
2 3 text3 7 9 T3 11 

EDIT1: Если вам нужно объединить в несколько столбцов:

print (mi) 
    A  B  C 
    AA BB1 BB2 CC 
0 1 text 5 7 
1 2 text2 6 8 
2 3 text3 7 9 

cols = list(zip(si.columns, range(si.shape[1]))) 
si.columns = pd.MultiIndex.from_tuples(cols) 
print (si) 
     A D E 
     0 1 2 
0 text T1 1 
1 text2 T2 2 
2 text3 T3 3 

df = (pd.merge(mi,si, left_on=[('B','BB1'),('A','AA')], right_on=[('A', 0), ('E', 2)]) 
     .drop([('A', 0), ('E', 2)], axis=1)) 

print (df) 
    A  B  C D 
    AA BB1 BB2 CC 1 
0 1 text 5 7 T1 
1 2 text2 6 8 T2 
2 3 text3 7 9 T3 
+0

Спасибо! Кстати, что, если бы я хотел, чтобы нижний набор столбцов в si был таким же, как верх (т.е. уровень 0 = «A», «D», «E» и уровень 1 = «A», «D», 'E'), таким образом, чтобы копировать верхний заголовок? –

+0

Отлично! Еще кое-что; что, если мне нужно присоединиться к нескольким столбцам? Я попробовал right_on = [(col1, col1), (col2, col2)], но не повезло. –

+0

Интересно, для меня это работает, см. Edit1. – jezrael