पंडों में शामिल होने और विलय के बीच क्या अंतर है?


208

मान लीजिए कि मेरे पास दो DataFrames हैं जैसे:

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

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

मैं उनका विलय करना चाहता हूं, इसलिए मैं कुछ इस तरह की कोशिश करता हूं:

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

और मैं खुश हूं

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

लेकिन मैं शामिल होने की विधि का उपयोग करने की कोशिश कर रहा हूं, जो मुझे विश्वास है कि बहुत समान है।

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

और मुझे यह मिलता है:

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

मैं क्या खो रहा हूँ?


4
विशिष्ट समस्या है कि यहाँ है mergeके स्तंभों मिलती है leftके स्तंभों को rightजो है तुम क्या चाहते है, लेकिन join(... on=[...])के कॉलम में शामिल leftके सूचकांक चाबियाँ करने के लिए rightहै, जो नहीं है तुम क्या चाहते। अधिक जानकारी के लिए नीचे मेरा उत्तर देखें।
मथायस फ्रीप

3
DataFrame.join () हमेशा कॉलर्स इंडेक्स या कुंजी ( onविकल्प द्वारा निर्दिष्ट ) के साथ मेल करना चाहता है other। याद रखें, शामिल होने के लिए अनुक्रमणिका। जबकि मर्ज () एक अधिक सामान्य विधि है।
झांग

जवाबों:


87

मैं हमेशा joinसूचकांकों पर उपयोग करता हूं :

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

mergeस्तंभों का उपयोग करके समान कार्यक्षमता हो सकती है:

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

त्रुटि यह कहती हुई प्रतीत होती है कि यह उम्मीद करता है कि मल्टी इंडेक्स rightउस पर उतनी ही गहराई से हो जितनी लंबाई पर on। यह मेरे लिए समझ में आता है। मैं स्वीकार कर सकता हूं कि शब्दार्थ अलग हैं। लेकिन मैं यह जानना चाहूंगा कि क्या मुझे df.join के साथ वैसा ही व्यवहार मिल सकता है
Munk

345

pandas.merge() सभी मर्ज / जुड़ने के व्यवहार के लिए उपयोग किया जाने वाला अंतर्निहित कार्य है।

DataFrames क्षमताओं को एक्सेस करने के लिए एक सुविधाजनक तरीके के रूप में pandas.DataFrame.merge()और pandas.DataFrame.join()तरीके प्रदान करता है pandas.merge()। उदाहरण के लिए, df1.merge(right=df2, ...)के बराबर है pandas.merge(left=df1, right=df2, ...)

इन दोनों के बीच मुख्य अंतर हैं df.join()और df.merge():

  1. राइट टेबल पर देखना: df1.join(df2)हमेशा के सूचकांक से जुड़ता है df2, लेकिन (डिफ़ॉल्ट) या (के साथ ) के df1.merge(df2)एक या अधिक कॉलम से जुड़ सकता है ।df2df2right_index=True
  2. बाईं मेज पर देखना: डिफ़ॉल्ट रूप से, df1.join(df2)के सूचकांक का उपयोग करता है df1और df1.merge(df2)कॉलम (एस) का उपयोग करता है df1। जिसे निर्दिष्ट करके df1.join(df2, on=key_or_keys)या उसके द्वारा ओवरराइड किया जा सकता है df1.merge(df2, left_index=True)
  3. लेफ्ट बनाम इनर जॉइन: df1.join(df2)लेफ्ट बाई डिफॉल्ट रूप से जुड़ता है (सभी पंक्तियों को रखता है df1), लेकिन df.mergeएक इनर डिफॉल्ट रूप से जुड़ता है (रिटर्न केवल मेलिंग पंक्तियों का ) df1और df2

तो, जेनेरिक दृष्टिकोण का उपयोग करना है pandas.merge(df1, df2)या df1.merge(df2)। लेकिन कई सामान्य स्थितियों के लिए ( df1किसी अनुक्रमणिका में सभी पंक्तियों को शामिल करना और रखना df2), आप df1.join(df2)इसके बजाय कुछ टाइपिंग को सहेज सकते हैं ।

प्रलेखन से इन मुद्दों पर कुछ नोट्स http://pandas.pydata.org/pandas-docs/stable/merging.html#database-style-dataframe-joining-merging :

merge पंडों के नाम स्थान में एक फ़ंक्शन है, और यह डेटाफ़्रेम उदाहरण विधि के रूप में भी उपलब्ध है, जिसमें कॉलिंगफ़्रेम को अंतर्निहित रूप से बाएं ऑब्जेक्ट में शामिल माना जाता है।

संबंधित DataFrame.joinविधि, mergeइंडेक्स-ऑन-इंडेक्स और इंडेक्स-ऑन-कॉलम (ओं) के लिए आंतरिक रूप से उपयोग करती है , लेकिन सामान्य कॉलम (के लिए डिफ़ॉल्ट व्यवहार merge) पर जुड़ने की कोशिश करने के बजाय डिफ़ॉल्ट रूप से अनुक्रमित पर मिलती है । यदि आप इंडेक्स में शामिल हो रहे हैं, तो आप DataFrame.joinअपने आप को कुछ टाइपिंग को बचाने के लिए उपयोग करना चाह सकते हैं ।

...

ये दो फ़ंक्शन कॉल पूरी तरह से बराबर हैं:

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

18
यह निश्चित रूप से स्वीकृत उत्तर होना चाहिए!
तेरह

@ मैथियास फ्रायप, शायद अधिक अनुभवी के लिए यह बिना कहे चला जाता है, लेकिन यह भी कहा जा सकता है कि "सही तालिका पर खोज: df1.join (df2) को df1.join (d2), = key_or_keys?
spacedustpi

@spacedustpi, मुझे लगता है कि आप कह रहे हैं कि आप on=key_or_keysसही तालिका में पंक्तियों के पाए जाने के तरीके का उपयोग कर सकते हैं । हालाँकि, वास्तव में ऐसा नहीं है। onतर्क पर देखने में परिवर्तन बाईं तालिका ( df1स्तंभ (ओं) को सूचकांक से)। हालांकि, इस तर्क के साथ भी, सही तालिका ( df2) को इसके सूचकांक के माध्यम से मिलान किया जाएगा। (ऊपर दिया गया अंतिम उदाहरण देखें।)
मथायस फ्रैप

इन स्थितियों से निपटने के लिए पंडों के पास कई तरीके हैं, उनमें शामिल होना, जुड़ना, जुड़ना, समागम, गठबंधन, गठबंधन_फर्स्ट। इनमें से प्रत्येक पर एक नज़र डालें, जिसके बारे में आपकी स्थिति के लिए सबसे उपयुक्त होगा
xiaxio

13

मेरा मानना ​​है कि join()यह सिर्फ एक सुविधा पद्धति है। df1.merge(df2)इसके बजाय प्रयास करें , जो आपको निर्दिष्ट करने की अनुमति देता है left_onऔर 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

से इस दस्तावेज़

पांडा एक एकल फ़ंक्शन प्रदान करता है, मर्ज करता है, क्योंकि सभी मानक डेटाबेस के लिए प्रवेश बिंदु 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)

तथा :

DataFrame.joinदो संभावित रूप से अनुक्रमित DataFrames के स्तंभों को एक ही परिणाम DataFrame में संयोजित करने के लिए एक सुविधाजनक विधि है। यहां एक बहुत ही बुनियादी उदाहरण है: यहां डेटा संरेखण अनुक्रमित (पंक्ति लेबल) पर है। यह वही व्यवहार मर्ज प्लस अतिरिक्त तर्कों का उपयोग करके प्राप्त किया जा सकता है जो इसे अनुक्रमित करने के लिए निर्देश देता है:

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

8

एक अंतर यह है कि mergeएक नया सूचकांक बना रहा है, और joinबाईं ओर सूचकांक बना रहा है। यदि आप गलत तरीके से यह मान लेते हैं कि आपका सूचकांक नहीं बदला गया है तो इसका आपके बाद के परिवर्तनों पर एक बड़ा परिणाम हो सकता है merge

उदाहरण के लिए:

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

वह सही है। यदि हम दो डेटा फ़्रेमों को सूचकांकों के अलावा अन्य स्तंभों में मर्ज करते हैं, तो हमें एक नया इंडेक्स मिलेगा, लेकिन यदि हम दोनों डेटा फ़्रेम्स के सूचकांकों में विलय करते हैं, तो हमें एक ही इंडेक्स के साथ एक डेटा फ़्रेम मिलेगा। इसलिए, मर्ज के बाद समान इंडेक्स प्राप्त करने के लिए हम दोनों डेटा फ़्रेमों के लिए कॉलम को अपना इंडेक्स (जिस पर हम मर्ज करना चाहते हैं) बना सकते हैं और फिर नए बनाए गए इंडेक्स पर डेटा फ़्रेम मर्ज कर सकते हैं।
हसन नजीब

बहुत ही खुशनुमा। मुझे कभी भी अनुक्रमण की आवश्यकता नहीं है (मैं सामान्य रूप से सिर्फ अनुक्रमणिका को रीसेट करता हूं) लेकिन यह कुछ मामलों में बड़ा बदलाव ला सकता है।
आइरन

4
  • ज्वाइन करें: डिफॉल्ट इंडेक्स (यदि कोई समान कॉलम नाम है, तो वह डिफॉल्ट मोड में एक एरर फेंक देगा क्योंकि u ने lsuffix या rsuffix को परिभाषित नहीं किया है)
df_1.join(df_2)
  • मर्ज: डिफ़ॉल्ट समान कॉलम नाम (यदि कोई समान कॉलम नाम नहीं है, तो यह डिफ़ॉल्ट मोड में एक त्रुटि फेंक देगा)
df_1.merge(df_2)
  • on दोनों मामलों में पैरामीटर का अलग-अलग अर्थ है
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 में समान रूप से रखने के लिए "पंडों का मर्ज बाहरी / आंतरिक जुड़ाव है और पंडों का जुड़ना प्राकृतिक जुड़ाव है"। इसलिए जब आप पंडों में मर्ज का उपयोग करते हैं, तो आप यह निर्दिष्ट करना चाहते हैं कि आप किस प्रकार की चौकोर जुड़ाव का उपयोग करना चाहते हैं, जबकि जब आप पंडों में शामिल होते हैं, तो आप वास्तव में मेल खाते हुए एक कॉलम लेबल रखना चाहते हैं ताकि यह सुनिश्चित हो सके

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.