Apa perbedaan antara bergabung dan bergabung di Panda?


208

Misalkan saya memiliki dua DataFrames seperti itu:

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

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

Saya ingin menggabungkan mereka, jadi saya mencoba sesuatu seperti ini:

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

Dan saya senang

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

Tapi saya mencoba menggunakan metode join, yang saya percaya sangat mirip.

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

Dan saya mendapatkan ini:

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

Apa yang saya lewatkan?


4
Masalah khusus di sini adalah bahwa mergebergabung dengan kolom leftke kolom right, yang adalah apa yang Anda inginkan, tetapi join(... on=[...])bergabung dengan kolom leftuntuk kunci indeks right, yang bukan yang Anda inginkan. Lihat jawaban saya di bawah ini untuk lebih jelasnya.
Matthias Fripp

3
DataFrame.join () selalu ingin mencocokkan indeks atau kunci penelepon (ditentukan oleh onopsi) terhadap otherindeks. Ingat, indeks untuk bergabung. Sedangkan merge () adalah metode yang lebih umum.
Jiapeng Zhang

Jawaban:


87

Saya selalu menggunakan joinindeks:

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

Fungsionalitas yang sama dapat diperoleh dengan menggunakan mergepada kolom berikut:

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

Kesalahan tampaknya mengatakan bahwa ia mengharapkan indeks multi pada rightkedalaman yang sama dengan panjang pada on. Bagi saya itu masuk akal. Saya dapat menerima bahwa semantiknya berbeda. Tapi saya ingin tahu apakah saya bisa mendapatkan perilaku yang sama dengan df.join
munk

346

pandas.merge() adalah fungsi dasar yang digunakan untuk semua perilaku gabungan / gabung.

DataFrames menyediakan pandas.DataFrame.merge()dan pandas.DataFrame.join()metode sebagai cara mudah untuk mengakses kemampuan pandas.merge(). Misalnya, df1.merge(right=df2, ...)setara dengan pandas.merge(left=df1, right=df2, ...).

Ini adalah perbedaan utama antara df.join()dan df.merge():

  1. pencarian di tabel kanan: df1.join(df2)selalu bergabung melalui indeks df2, tetapi df1.merge(df2)dapat bergabung ke satu atau beberapa kolom df2(default) atau ke indeks df2(dengan right_index=True).
  2. pencarian di tabel sebelah kiri: secara default, df1.join(df2)menggunakan indeks df1dan df1.merge(df2)menggunakan kolom df1. Itu dapat diganti dengan menentukan df1.join(df2, on=key_or_keys)atau df1.merge(df2, left_index=True).
  3. kiri vs gabungan dalam: df1.join(df2)apakah gabungan kiri secara default (membuat semua baris df1), tetapi df.mergeapakah gabungan internal secara default (hanya mengembalikan baris yang cocok dengan df1dan df2).

Jadi, pendekatan generik adalah menggunakan pandas.merge(df1, df2)atau df1.merge(df2). Tetapi untuk sejumlah situasi umum (menjaga semua baris df1dan bergabung dengan indeks df2), Anda dapat menyimpan beberapa pengetikan dengan menggunakan df1.join(df2)sebagai gantinya.

Beberapa catatan tentang masalah ini dari dokumentasi di http://pandas.pydata.org/pandas-docs/stable/merging.html#database-style-dataframe-joining-merging :

merge adalah fungsi di namespace panda, dan juga tersedia sebagai metode instance DataFrame, dengan pemanggilan DataFrame secara implisit dianggap sebagai objek kiri dalam gabungan.

DataFrame.joinMetode terkait , digunakan secara mergeinternal untuk indeks-on-indeks dan indeks-on-kolom bergabung, tetapi bergabung pada indeks secara default daripada mencoba untuk bergabung pada kolom umum (perilaku default untuk merge). Jika Anda bergabung dalam indeks, Anda mungkin ingin menggunakannya DataFrame.joinuntuk menyelamatkan diri Anda dari mengetik.

...

Kedua panggilan fungsi ini sepenuhnya setara:

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

19
Ini pastinya jawaban yang diterima! Terima kasih atas penjelasan Anda
Yohan Obadia

@Matthias Fripp, Mungkin untuk yang lebih berpengalaman tidak perlu dikatakan, tetapi bisa juga dikatakan bahwa "pencarian di meja sebelah kanan: df1.join (df2) dapat diganti ke df1.join (df2, pada = key_or_keys?
spacedustpi

@spaceustpi, saya pikir Anda mengatakan bahwa Anda dapat menggunakan on=key_or_keysuntuk mengubah cara baris ditemukan di tabel kanan. Namun, sebenarnya bukan itu masalahnya. The onargumen mengubah lookup di sebelah kiri meja ( df1) dari indeks ke kolom (s). Namun, bahkan dengan argumen ini, tabel kanan ( df2) akan dicocokkan melalui indeksnya. (Lihat contoh terakhir di atas.)
Matthias Fripp

Panda memiliki beberapa metode untuk menghadapi situasi ini, di antaranya menggabungkan, bergabung, menambahkan, menyatukan, menggabungkan, menggabungkan_first. Lihatlah masing-masing untuk melihat sekilas mana yang paling cocok untuk situasi Anda
xiaxio

13

Saya percaya itu join()hanya metode kenyamanan. Coba df1.merge(df2)saja, yang memungkinkan Anda menentukan left_ondan right_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

Dari dokumentasi ini

panda menyediakan fungsi tunggal, menggabungkan, sebagai titik masuk untuk semua operasi gabungan basis data standar antara objek 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)

Dan:

DataFrame.joinadalah metode yang mudah untuk menggabungkan kolom dari dua DataFrames yang berpotensi diindeks berbeda ke dalam DataFrame hasil tunggal. Berikut adalah contoh yang sangat mendasar: Penyelarasan data di sini ada di indeks (label baris). Perilaku yang sama ini dapat dicapai menggunakan gabungan ditambah argumen tambahan yang memerintahkannya untuk menggunakan indeks:

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

8

Salah satu perbedaannya adalah mergemembuat indeks baru, dan joinmenjaga indeks sisi kiri. Ini dapat memiliki konsekuensi besar pada transformasi Anda nanti jika Anda salah berasumsi bahwa indeks Anda tidak berubah merge.

Sebagai contoh:

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

Itu betul. Jika kita menggabungkan dua frame data pada kolom selain indeks kita akan mendapatkan indeks baru tetapi jika kita menggabungkan indeks kedua frame data kita akan mendapatkan frame data dengan indeks yang sama. Jadi, untuk mendapatkan indeks yang sama setelah penggabungan, kami dapat membuat kolom indeks kami (yang ingin kami gabungkan) untuk kedua frame data dan kemudian menggabungkan frame data pada indeks yang baru dibuat.
hasan najeeb

Sangat mendalam. Saya tidak pernah membutuhkan pengindeksan (saya biasanya hanya mengatur ulang indeks) tetapi ini bisa membuat perbedaan besar dalam beberapa kasus.
irene

4
  • Bergabung: Indeks Default (Jika ada nama kolom yang sama maka itu akan menimbulkan kesalahan dalam mode default karena Anda belum mendefinisikan lsuffix atau rsuffix))
df_1.join(df_2)
  • Gabung: Nama Kolom Sama Sama (Jika tidak ada nama kolom yang sama, akan terjadi kesalahan dalam mode default)
df_1.merge(df_2)
  • on parameter memiliki arti berbeda dalam kedua kasus
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

Untuk menaruhnya secara analog ke SQL "Gabungan panda adalah untuk bagian luar / bagian dalam dan panda bergabung adalah bagian dari gabungan alami". Karenanya saat Anda menggunakan penggabungan dalam panda, Anda ingin menentukan jenis bahasa gabung mana yang ingin Anda gunakan sedangkan ketika Anda menggunakan panda bergabung, Anda benar-benar ingin memiliki label kolom yang cocok untuk memastikan itu bergabung

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.