2017-01-02 55 views
5

Chciałbym wykonać samo łączenie na ramce danych Pandy, aby niektóre wiersze zostały dołączone do oryginalnych wierszy. Każdy wiersz ma znacznik "i" wskazujący, który wiersz powinien zostać dołączony do niego po prawej stronie.samodzielne łączenie z Pandami

d = pd.DataFrame(['A','B','C'], columns = ['some_col']) 
d['i'] = [2,1,1] 

In [17]: d 
Out[17]: 
    some_col i 
0  A 2 
1  B 1 
2  C 1 

sygnał wyjściowy:

some_col i some_col_y 
0  A 2   C 
1  B 1   B 
2  C 1   B 

Oznacza to, że rząd 2 zostaje dołączony do rzędu 0, wiersz 1 do wiersza 1, rzędu 1 do rzędu 2 (jak pokazano w I).

Mój pomysł na to, jak się do tego zabrać był

pd.merge(d, d, left_index = True, right_on = 'i', how = 'left') 

Ale to daje zupełnie coś innego. Jak zrobić to poprawnie?

Odpowiedz

3

join z on='i'

d.join(d.drop('i', 1), on='i', rsuffix='_y') 

    some_col i some_col_y 
0  A 2   C 
1  B 1   B 
2  C 1   B 
1

Spróbuj tego:

In [69]: d.join(d.set_index('i'), rsuffix='_y') 
Out[69]: 
    some_col i some_col_y 
0  A 2  NaN 
1  B 1   B 
1  B 1   C 
2  C 1   A 

czyli

In [64]: pd.merge(d[['some_col']], d, left_index=True, right_on='i', suffixes=['_y','']).sort_index() 
Out[64]: 
    some_col_y some_col i 
0   C  A 2 
1   B  B 1 
2   B  C 1 
4

Zamiast merge można również użyć indeksowania i przypisania:

>>> d['new_col'] = d['some_col'][d['i']].values 
>>> d 
    some_col i new_col 
0  A 2  C 
1  B 1  B 
2  C 1  B 
+0

Podoba mi się twoja odpowiedź bardziej niż moja. Jeśli OP potrzebuje wirtualnej kolumny - można to zrobić w następujący sposób: 'd.assign (some_col_y = d ['some_col']. Loc [d ['i']]. Values)' – MaxU