2017-01-02 23 views
5

Tôi muốn thực hiện tự tham gia trên một khung dữ liệu Pandas để một số hàng được nối vào hàng gốc. Mỗi hàng có một điểm đánh dấu 'i' cho biết hàng nào sẽ được thêm vào nó ở bên phải.tự tham gia với Pandas

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 

đầu ra mong muốn:

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

Đó là, dòng 2 được gắn vào hàng 0, dòng 1 chèo 1, dòng 1 chèo 2 (như được chỉ ra bởi i).

Ý tưởng của tôi như thế nào để đi về nó là

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

Nhưng nó tạo ra một cái gì đó khác hoàn toàn. Làm thế nào để làm điều đó một cách chính xác?

Trả lời

3

join với 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

Hãy thử điều này:

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 

hay:

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

Thay vì sử dụng merge bạn cũng có thể sử dụng lập chỉ mục và phân công:

>>> 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

Tôi thích câu trả lời của bạn nhiều hơn tôi. Nếu OP cần một cột ảo - nó có thể được thực hiện theo cách này: 'd.assign (some_col_y = d ['some_col']. Loc [d ['i']]. Values)' – MaxU