2015-05-05 38 views
8

Tôi mới vào gấu trúc và dường như không thể có được điều này để làm việc với chức năng hợp nhất hiện có:gấu trúc còn lại tham gia và cập nhật cột

>>> left  >>> right 
    a b c  a c d 
0 1 4 9 0 1 7 13 
1 2 5 10 1 2 8 14 
2 3 6 11 2 3 9 15 
3 4 7 12  

Với một trái tham gia trên cột một, tôi muốn để cập nhật thông thường cột THEO CÁC BÀI VIẾT THAM GIA. Lưu ý giá trị cuối cùng trong cột c là từ bảng LEFT vì không có kết quả phù hợp.

>>> final  
    a b c d 
0 1 4 7 13 
1 2 5 8 14 
2 3 6 9 15 
3 4 7 12 NAN 

Tôi nên làm như thế nào với chức năng hợp nhất Pandas? Cảm ơn bạn.

Trả lời

11

Một cách để làm điều này là để thiết lập một cột như chỉ số và update:

In [11]: left_a = left.set_index('a') 

In [12]: right_a = right.set_index('a') 

Lưu ý: update chỉ thực hiện một tham gia bên trái (không hợp nhất), do đó, cũng như set_index bạn cũng cần bao gồm các cột bổ sung không có trong left_a.

In [13]: res = left_a.loc[:, left_a.columns.union(right_a.columns)] 

In [14]: res.update(right_a) 

In [15]: res 
Out[15]: 
    b c d 
a 
1 4 7 13 
2 5 8 14 
3 6 9 15 
4 7 12 NaN 
+0

Cảm ơn bạn! Không hiểu tại sao điều này không được xây dựng trong .. – iwbabn

+1

Cảnh báo cho những người trong số các bạn triển khai giải pháp này: Trong những điều kiện nhất định, số nguyên dtypes được thay đổi để nổi! http://stackoverflow.com/questions/17398216/unwanted-type-conversion-in-pandas-dataframe-update – ssoler

8

Bạn có thể sử dụng merge() giữa leftright với how='left' trên cột 'a'.

In [74]: final = left.merge(right, on='a', how='left') 

In [75]: final 
Out[75]: 
    a b c_x c_y d 
0 1 4 9 7 13 
1 2 5 10 8 14 
2 3 6 11 9 15 
3 4 7 12 NaN NaN 

Thay NaN giá trị từ c_y với giá trị c_x

In [76]: final['c'] = final['c_y'].fillna(final['c_x']) 

In [77]: final 
Out[77]: 
    a b c_x c_y d c 
0 1 4 9 7 13 7 
1 2 5 10 8 14 8 
2 3 6 11 9 15 9 
3 4 7 12 NaN NaN 12 

Drop cột không mong muốn, và bạn đã các resilt

In [79]: final.drop(['c_x', 'c_y'], axis=1) 
Out[79]: 
    a b d c 
0 1 4 13 7 
1 2 5 14 8 
2 3 6 15 9 
3 4 7 NaN 12 
+0

Fillna đó (với một cột khác) khá gọn gàng! – fixxxer

+0

Tôi thích phương pháp này tốt hơn so với câu trả lời được chấp nhận bởi vì nó không phụ thuộc vào hai DataFrames có một biến khóa tham gia ('a' trong ví dụ này) chung. – blahblahetcetc

+0

Tôi liên tục nhận được lỗi này khi tôi sử dụng mã này: FutureWarning: Chuyển danh sách thích thành .loc hoặc [] với bất kỳ nhãn bị thiếu nào sẽ tăng Lỗi chính trong tương lai, bạn có thể sử dụng .reindex() làm phương án thay thế. Suy nghĩ duy nhất của tôi là dfs của tôi có thể không chia sẻ cùng một cột? Đó không phải là câu trả lời ban đầu được cho là đúng không? – conchoecia

1

Dưới đây là một cách để làm điều đó với join:

In [632]: t = left.set_index('a').join(right.set_index('a'), rsuffix='_right') 

In [633]: t 
Out[633]: 
    b c c_right d 
a      
1 4 9  7 13 
2 5 10  8 14 
3 6 11  9 15 
4 7 12  NaN NaN 

Bây giờ, chúng tôi muốn đặt giá trị null là c_right (là từ dataframe right) với các giá trị từ c cột từ khung dữ liệu left. Cập nhật quá trình dưới đây với một phương pháp lấy từ câu trả lời @ John Galt của

In [657]: t['c_right'] = t['c_right'].fillna(t['c']) 

In [658]: t 
Out[658]: 
    b c c_right d 
a      
1 4 9  7 13 
2 5 10  8 14 
3 6 11  9 15 
4 7 12  12 NaN 

In [659]: t.drop('c_right', axis=1) 
Out[659]: 
    b c d 
a   
1 4 9 13 
2 5 10 14 
3 6 11 15 
4 7 12 NaN 
Các vấn đề liên quan