Sự khác biệt giữa tham gia và hợp nhất trong Pandas là gì?


208

Giả sử tôi có hai DataFram như vậy:

left = pd.DataFrame({'key1': ['foo', 'bar'], 'lval': [1, 2]})

right = pd.DataFrame({'key2': ['foo', 'bar'], 'rval': [4, 5]})

Tôi muốn hợp nhất chúng, vì vậy tôi thử một cái gì đó như thế này:

pd.merge(left, right, left_on='key1', right_on='key2')

Và tôi hạnh phúc

    key1    lval    key2    rval
0   foo     1       foo     4
1   bar     2       bar     5

Nhưng tôi đang cố gắng sử dụng phương thức tham gia mà tôi đã tin là khá giống nhau.

left.join(right, on=['key1', 'key2'])

Và tôi nhận được điều này:

//anaconda/lib/python2.7/site-packages/pandas/tools/merge.pyc in _validate_specification(self)
    406             if self.right_index:
    407                 if not ((len(self.left_on) == self.right.index.nlevels)):
--> 408                     raise AssertionError()
    409                 self.right_on = [None] * n
    410         elif self.right_on is not None:

AssertionError: 

Tôi đang thiếu gì?


4
Vấn đề cụ thể ở đây là mergetham gia các cột của leftcác cột right, đó là những gì bạn muốn, nhưng join(... on=[...])tham gia các cột của leftcác khóa chỉ mục của right, đó không phải là những gì bạn muốn. Xem câu trả lời của tôi dưới đây để biết thêm chi tiết.
Matthias Fripp

3
DataFrame.join () luôn muốn khớp các chỉ mục hoặc khóa của người gọi (được chỉ định bởi ontùy chọn) so với các otherchỉ mục của. Hãy nhớ rằng, các chỉ mục để tham gia. Trong khi merge () là một phương thức chung hơn.
Jiapeng Zhang

Câu trả lời:


87

Tôi luôn luôn sử dụng jointrên các chỉ số:

import pandas as pd
left = pd.DataFrame({'key': ['foo', 'bar'], 'val': [1, 2]}).set_index('key')
right = pd.DataFrame({'key': ['foo', 'bar'], 'val': [4, 5]}).set_index('key')
left.join(right, lsuffix='_l', rsuffix='_r')

     val_l  val_r
key            
foo      1      4
bar      2      5

Các chức năng tương tự có thể có bằng cách sử dụng mergetrên các cột sau:

left = pd.DataFrame({'key': ['foo', 'bar'], 'val': [1, 2]})
right = pd.DataFrame({'key': ['foo', 'bar'], 'val': [4, 5]})
left.merge(right, on=('key'), suffixes=('_l', '_r'))

   key  val_l  val_r
0  foo      1      4
1  bar      2      5

Lỗi dường như đang nói rằng nó hy vọng đa chỉ số trên rightđó có cùng độ sâu với độ dài trên on. Điều đó có ý nghĩa với tôi loại. Tôi có thể chấp nhận rằng ngữ nghĩa là khác nhau. Nhưng tôi muốn biết nếu tôi có thể nhận được rằng hành vi tương tự với df.join
munk

345

pandas.merge() là hàm cơ bản được sử dụng cho tất cả các hành vi hợp nhất / nối.

DataFrames cung cấp pandas.DataFrame.merge()pandas.DataFrame.join()các phương thức như một cách thuận tiện để truy cập các khả năng của pandas.merge(). Ví dụ, df1.merge(right=df2, ...)tương đương với pandas.merge(left=df1, right=df2, ...).

Đây là những khác biệt chính giữa df.join()df.merge():

  1. tra cứu trên bảng bên phải: df1.join(df2)luôn tham gia thông qua chỉ mục của df2, nhưng df1.merge(df2)có thể tham gia vào một hoặc nhiều cột của df2(mặc định) hoặc chỉ mục của df2(với right_index=True).
  2. tra cứu trên bảng bên trái: theo mặc định, df1.join(df2)sử dụng chỉ mục df1df1.merge(df2)sử dụng (các) cột của df1. Điều đó có thể được ghi đè bằng cách chỉ định df1.join(df2, on=key_or_keys)hoặc df1.merge(df2, left_index=True).
  3. trái vs bên tham gia: df1.join(df2)không một trái tham gia theo mặc định (giữ tất cả hàng df1), nhưng df.mergekhông một bên tham gia theo mặc định (lợi nhuận chỉ phù hợp với các hàng df1df2).

Vì vậy, cách tiếp cận chung là sử dụng pandas.merge(df1, df2)hoặc df1.merge(df2). Nhưng đối với một số tình huống phổ biến (giữ tất cả các hàng df1và tham gia vào một chỉ mục df2), bạn có thể lưu một số cách gõ bằng cách sử dụng df1.join(df2)thay thế.

Một số lưu ý về các vấn đề này từ tài liệu tại http://pandas.pydata.org/pandas-docs/urdy/merging.html#database-style-dataframe-joining-merging :

merge là một hàm trong không gian tên gấu trúc và nó cũng có sẵn như là một phương thức đối tượng DataFrame, với việc gọi DataFrame được coi là đối tượng bên trái trong phép nối.

DataFrame.joinPhương thức liên quan , sử dụng mergenội bộ cho các tham gia index-on-index và index-on-cột, nhưng tham gia vào các chỉ mục theo mặc định thay vì cố gắng tham gia vào các cột chung (hành vi mặc định cho merge). Nếu bạn đang tham gia vào chỉ mục, bạn có thể muốn sử dụng DataFrame.joinđể tiết kiệm cho mình một số thao tác gõ.

...

Hai lệnh gọi hàm này hoàn toàn tương đương:

left.join(right, on=key_or_keys)
pd.merge(left, right, left_on=key_or_keys, right_index=True, how='left', sort=False)

18
Đây chắc chắn là câu trả lời được chấp nhận! Cảm ơn lời giải thích đầy đủ
Yohan Obadia

@Matthias Fripp, Có lẽ đối với nhiều kinh nghiệm nó đi mà không nói, nhưng nó cũng có thể nói rằng "tra cứu trên bảng bên phải: df1.join (df2) có thể được ghi đè để df1.join (df2, trên = key_or_keys
spacedustpi

@spacesustpi, tôi nghĩ rằng bạn đang nói rằng bạn có thể sử dụng on=key_or_keysđể thay đổi cách tìm thấy các hàng trong bảng bên phải. Tuy nhiên, đó không thực sự là trường hợp. Đối onsố thay đổi tra cứu trên bảng bên trái ( df1) từ chỉ mục sang cột (s). Tuy nhiên, ngay cả với đối số này, bảng bên phải ( df2) sẽ được khớp thông qua chỉ mục của nó. (Xem ví dụ cuối cùng ở trên.)
Matthias Fripp

Pandas có một số phương pháp để đối phó với các tình huống này, trong số đó có hợp nhất, nối, nối, nối, kết hợp, kết hợp_first. Hãy nhìn vào từng cái này để có cái nhìn thoáng qua về cái nào sẽ phù hợp nhất với tình huống của bạn
xiaxio

13

Tôi tin rằng đó join()chỉ là một phương pháp thuận tiện. df1.merge(df2)Thay vào đó, hãy thử , cho phép bạn chỉ định left_onright_on:

In [30]: left.merge(right, left_on="key1", right_on="key2")
Out[30]: 
  key1  lval key2  rval
0  foo     1  foo     4
1  bar     2  bar     5

11

Từ tài liệu này

gấu trúc cung cấp một hàm duy nhất, hợp nhất, làm điểm vào cho tất cả các hoạt động nối cơ sở dữ liệu tiêu chuẩn giữa các đối tượng DataFrame:

merge(left, right, how='inner', on=None, left_on=None, right_on=None,
      left_index=False, right_index=False, sort=True,
      suffixes=('_x', '_y'), copy=True, indicator=False)

Và:

DataFrame.joinlà một phương pháp thuận tiện để kết hợp các cột của hai DataFram có khả năng được lập chỉ mục khác nhau thành một DataFrame kết quả duy nhất. Đây là một ví dụ rất cơ bản: Căn chỉnh dữ liệu ở đây là trên các chỉ mục (nhãn hàng). Hành vi tương tự này có thể đạt được bằng cách sử dụng hợp nhất cộng với các đối số bổ sung hướng dẫn nó sử dụng các chỉ mục:

result = pd.merge(left, right, left_index=True, right_index=True,
how='outer')

8

Một trong những khác biệt là mergetạo ra một chỉ mục mới và joingiữ chỉ mục bên trái. Nó có thể có một hậu quả lớn đối với các biến đổi sau này của bạn nếu bạn sai khi cho rằng chỉ mục của bạn không thay đổi merge.

Ví dụ:

import pandas as pd

df1 = pd.DataFrame({'org_index': [101, 102, 103, 104],
                    'date': [201801, 201801, 201802, 201802],
                    'val': [1, 2, 3, 4]}, index=[101, 102, 103, 104])
df1

       date  org_index  val
101  201801        101    1
102  201801        102    2
103  201802        103    3
104  201802        104    4

-

df2 = pd.DataFrame({'date': [201801, 201802], 'dateval': ['A', 'B']}).set_index('date')
df2

       dateval
date          
201801       A
201802       B

-

df1.merge(df2, on='date')

     date  org_index  val dateval
0  201801        101    1       A
1  201801        102    2       A
2  201802        103    3       B
3  201802        104    4       B

-

df1.join(df2, on='date')
       date  org_index  val dateval
101  201801        101    1       A
102  201801        102    2       A
103  201802        103    3       B
104  201802        104    4       B

Đúng rồi. Nếu chúng ta hợp nhất hai khung dữ liệu trên các cột ngoài các chỉ mục, chúng ta sẽ nhận được một chỉ mục mới nhưng nếu chúng ta hợp nhất trên các chỉ mục của cả hai khung dữ liệu, chúng ta sẽ có được một khung dữ liệu có cùng chỉ mục. Vì vậy, để có được cùng một chỉ mục sau khi hợp nhất, chúng ta có thể tạo các cột chỉ mục của chúng ta (trên đó chúng ta muốn hợp nhất) cho cả hai khung dữ liệu và sau đó hợp nhất các khung dữ liệu trên chỉ mục mới được tạo.
hasan najeeb

Rất sâu sắc. Tôi chưa bao giờ cần lập chỉ mục (tôi thường chỉ đặt lại chỉ mục) nhưng điều này có thể tạo ra sự khác biệt lớn trong một số trường hợp.
irene

4
  • Tham gia: Chỉ mục mặc định (Nếu có cùng tên cột thì nó sẽ xuất hiện lỗi trong chế độ mặc định vì bạn chưa xác định lsuffix hoặc rsuffix))
df_1.join(df_2)
  • Hợp nhất: Tên cột giống nhau mặc định (Nếu không có tên cột giống nhau, nó sẽ gây ra lỗi trong chế độ mặc định)
df_1.merge(df_2)
  • on tham số có ý nghĩa khác nhau trong cả hai trường hợp
df_1.merge(df_2, on='column_1')

df_1.join(df_2, on='column_1') // It will throw error
df_1.join(df_2.set_index('column_1'), on='column_1')

2

Nói một cách tương tự với SQL "Pandas merge là tham gia bên ngoài / bên trong và tham gia Pandas là tham gia tự nhiên". Do đó, khi bạn sử dụng hợp nhất trong gấu trúc, bạn muốn chỉ định loại tham gia sqlish nào bạn muốn sử dụng trong khi bạn sử dụng gấu trúc tham gia, bạn thực sự muốn có nhãn cột phù hợp để đảm bảo nó tham gia

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.