Pandalar'da birleştirme ve birleştirme arasındaki fark nedir?


208

Diyelim ki böyle iki DataFrames var:

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

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

Onları birleştirmek istiyorum, bu yüzden böyle bir şey deniyorum:

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

Ve ben mutluyum

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

Ama oldukça benzer olduğuna inandığım birleştirme yöntemini kullanmaya çalışıyorum.

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

Ve bunu anladım:

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

Neyi kaçırıyorum?


4
Buradaki belirli sorun merge, sütunlarını, leftistediğiniz sütunlar ile birleştirir right, ancak dizin anahtarlarının join(... on=[...])sütunlarını birleştirir , ki bu istediğiniz değildir. Daha fazla ayrıntı için aşağıdaki cevabıma bakın. leftright
Matthias Fripp

3
DataFrame.join () her zaman arayanın dizinlerini veya anahtarlarını (seçenekle belirtilir on) other'dizinleriyle karşılaştırmak ister. Unutmayın, katılmak için dizinler. While merge () daha genel bir yöntemdir.
Jiapeng Zhang

Yanıtlar:


87

Her zaman joinendekslerde kullanırım :

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

Aynı işlevler mergeaşağıdaki sütunlarda da kullanılabilir :

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

Hata, üzerinde çoklu indeksin rightuzunluğu ile aynı derinlikte beklediğini söylüyor gibi görünüyor on. Bu bana biraz mantıklı geliyor. Anlambilimin farklı olduğunu kabul edebilirim. Ama aynı davranışı df.join ile alabilir miyim bilmek istiyorum
munk

346

pandas.merge() tüm birleştirme / birleştirme davranışları için kullanılan temel işlevdir.

DataFrames, pandas.DataFrame.merge()ve pandas.DataFrame.join()yöntemlerinin özelliklerine erişmek için uygun bir yol sağlar pandas.merge(). Örneğin, df1.merge(right=df2, ...)eşdeğerdirpandas.merge(left=df1, right=df2, ...) .

Bunlar df.join()ve arasındaki temel farklar şunlardır df.merge():

  1. sağ tabloda arama: df1.join(df2)her zaman dizini aracılığıyla birleştirilir df2, ancak (varsayılan) df1.merge(df2)bir veya daha fazla sütuna df2veya df2(ile right_index=True) dizinine katılabilir .
  2. arama sol masada: varsayılan olarak, df1.join(df2)dizinini kullanır df1ve df1.merge(df2)kullanımları sütunu (ler) df1. df1.join(df2, on=key_or_keys)Veya belirtilerek geçersiz kılınabilir.df1.merge(df2, left_index=True) .
  3. sola karşı iç birleşim: df1.join(df2)varsayılan olarak sol birleşim yapar (tüm satırlarını tutar df1), ancak df.mergevarsayılan olarak iç birleşim yapar ( df1ve yalnızca eşleşen satırlarını döndürür df2).

Yani, genel yaklaşım pandas.merge(df1, df2)veya kullanmaktır df1.merge(df2). Ancak, bazı yaygın durumlar için (tüm satırları içeride tutarak df1ve bir dizine katılmadan df2), df1.join(df2)bunun yerine kullanarak bazı yazımları kaydedebilirsiniz .

Bu konulara ilişkin bazı notlar http://pandas.pydata.org/pandas-docs/stable/merging.html#database-style-dataframe-joining-merging adresindeki belgelerden alınmıştır :

merge pandaların ad alanında bir işlevdir ve aynı zamanda DataFrame örnek yöntemi olarak da kullanılabilir; çağıran DataFrame, örtülü olarak birleştirme içinde sol nesne olarak kabul edilir.

İlgili DataFrame.joinyöntem, mergedizin üzerinde dizin ve sütun üzerinde dizin birleşimleri için dahili olarak kullanılır, ancak ortak sütunlarda (varsayılan davranışı merge) birleştirilmeye çalışmak yerine varsayılan olarak dizinlerde birleşir . Dizine katılıyorsanız, DataFrame.joinkendinizi biraz yazmak için kullanmak isteyebilirsiniz .

...

Bu iki işlev çağrısı tamamen eşdeğerdir:

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

19
Bu kesinlikle kabul edilen cevap olmalı! Teşekkür açıklaması için teşekkürler
Yohan Obadia

@Matthias Fripp, daha söylemeye gerek yok, ama aynı zamanda sağ masaya arama" olduğu söylenebilir deneyimli Belki için:? Df1.join (df2) = key_or_keys üzerinde df1.join (df2, için geçersiz olabilir
spacedustpi

@spacedustpi, bence on=key_or_keyssatırların doğru tabloda bulunma şeklini değiştirmek için kullanabileceğinizi söylüyorsunuz . Ancak, durum böyle değildir. Bağımsız ondeğişken, sol tablodaki ( df1) aramayı dizinden sütunlara değiştirir. Bununla birlikte, bu argümanla bile, sağ tablo ( df2) indeksi ile eşleştirilecektir. (Yukarıdaki son örneğe bakın.)
Matthias Fripp

Pandaların bu durumlarla başa çıkmak için çeşitli yöntemleri vardır, aralarında birleştirmek, katılmak, eklemek, concat, birleştirmek, combine_first.
Hangisinin

13

Bunun join()sadece bir kolaylık yöntemi olduğuna inanıyorum . Deneyin df1.merge(df2)belirtmek olanak tanıyan yerine left_onve 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

Gönderen bu belgelerin

pandas, DataFrame nesneleri arasındaki tüm standart veritabanı birleştirme işlemleri için giriş noktası olarak tek bir işlev, birleştirme sağlar:

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)

Ve :

DataFrame.joinpotansiyel olarak farklı dizine eklenebilen iki DataFrame'in sütunlarını tek bir sonuç DataFrame'de birleştirmek için uygun bir yöntemdir. İşte çok temel bir örnek: Buradaki veri hizalaması dizinlerde (satır etiketleri). Aynı davranış, birleştirme artı dizinleri kullanmasını bildiren ek bağımsız değişkenler kullanılarak da gerçekleştirilebilir:

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

8

Farklardan biri, mergeyeni bir dizin oluşturmak joinve sol taraftaki dizini tutmaktır. Dizininizin değiştirilmediğini yanlış bir şekilde varsayarsanız, sonraki dönüşümlerinizde büyük bir sonuç olabilir.merge .

Örneğin:

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

Bu doğru. İki veri çerçevesini dizinler dışındaki sütunlarda birleştirirsek yeni bir dizin alırız, ancak her iki veri çerçevesinin dizinlerini birleştirirsek aynı dizine sahip bir veri çerçevesini alırız. Bu nedenle, birleştirme işleminden sonra aynı dizini elde etmek için, sütunları her iki veri çerçevesi için dizinimizi (üzerinde birleştirmek istediğimiz) yapabilir ve ardından yeni oluşturulan dizindeki veri çerçevelerini birleştirebiliriz.
hasan najeeb

Çok anlayışlı. Asla indekslemeye ihtiyacım olmadı (normalde indeksi sıfırladım) ama bu bazı durumlarda büyük bir fark yaratabilir.
irene

4
  • Birleştir: Varsayılan Dizin (Aynı sütun adı varsa, u lsuffix veya rsuffix tanımlanmadığı için varsayılan modda bir hata atar)
df_1.join(df_2)
  • Birleştirme: Varsayılan Aynı Sütun Adları (Aynı sütun adı yoksa, varsayılan modda hata verir)
df_1.merge(df_2)
  • on parametrenin her iki durumda da farklı bir anlamı vardır
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

SQL'e benzer şekilde koymak için "Pandalar birleşmesi dış / iç birleşimdir ve Pandalar birleşim doğal birleşimdir". Bu nedenle pandalarda birleştirme kullandığınızda, hangi tür sqlish birleşimini kullanmak istediğinizi belirtmek istersiniz, panda birleşimini kullandığınızda, birleşmesini sağlamak için gerçekten eşleşen bir sütun etiketine sahip olmak istersiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.