पांड मर्ज का उपयोग करते समय सूचकांक कैसे रखें


126

मैं दो विलय करना चाहूंगा DataFrames, और पहले फ्रेम से सूचकांक को विलय किए गए डेटासेट पर सूचकांक के रूप में रखना चाहूंगा । हालाँकि, जब मैं मर्ज करता हूं, तो परिणामी DataFrame में पूर्णांक अनुक्रमणिका होती है। मैं यह कैसे निर्दिष्ट कर सकता हूं कि मैं बाएं डेटा फ्रेम से सूचकांक रखना चाहता हूं?

In [4]: a = pd.DataFrame({'col1': {'a': 1, 'b': 2, 'c': 3}, 
                          'to_merge_on': {'a': 1, 'b': 3, 'c': 4}})

In [5]: b = pd.DataFrame({'col2': {0: 1, 1: 2, 2: 3}, 
                          'to_merge_on': {0: 1, 1: 3, 2: 5}})

In [6]: a
Out[6]:
   col1  to_merge_on
a     1            1
b     2            3
c     3            4

In [7]: b
Out[7]:
   col2  to_merge_on
0     1            1
1     2            3
2     3            5

In [8]: a.merge(b, how='left')
Out[8]:
   col1  to_merge_on  col2
0     1            1   1.0
1     2            3   2.0
2     3            4   NaN

In [9]: _.index
Out[9]: Int64Index([0, 1, 2], dtype='int64')

संपादित करें: आसानी से पुन: प्रस्तुत किया जा सकता है कि उदाहरण कोड के लिए बंद कर दिया


2
यदि आप किसी विशिष्ट कॉलम में विलय करते हैं, तो यह स्पष्ट नहीं है कि कौन से सूचकांकों का उपयोग करना है (यदि वे दोनों अलग हैं)।
बोनोबो

जवाबों:


161
In [5]: a.reset_index().merge(b, how="left").set_index('index')
Out[5]:
       col1  to_merge_on  col2
index
a         1            1     1
b         2            3     2
c         3            4   NaN

नोट: कुछ छोड़ दिया मर्ज के संचालन के लिए आप अधिक पंक्तियों के साथ अगर वहाँ के बीच कई मैचों हैं खत्म हो सकता है aऔर bऔर आप deduplicate करने के लिए (आवश्यकता होगी डिडुप्लीकेशन के लिए दस्तावेज़ )। यही कारण है कि पांडा आपके लिए सूचकांक नहीं रखते हैं।


4
बहुत चालाक। a.merge (b, how = "left")। set_index (a.index) भी काम करता है, लेकिन यह कम मज़बूत लगता है (चूंकि इसका पहला भाग इसे रीसेट करने से पहले सूचकांक मानों को खो देता है।)
Danbox

11
इस विशेष मामले के लिए, वे समकक्ष हैं। लेकिन कई मर्ज संचालन के लिए, परिणामी फ्रेम में मूल aफ्रेम की तुलना में पंक्तियों की संख्या समान नहीं है । रीसेट_इंडेक्स इंडेक्स को एक नियमित कॉलम में ले जाता है और मर्ज ऑपरेशन के कारण एक पंक्ति की डुप्लिकेट / हटाए जाने के बाद मर्ज होने के बाद भी इस कॉलम से सेट_इंडेक्स का ध्यान रखा जाता है।
राउटर ओवरमीयर

1
@ राउटर मुझे यह जानकर अच्छा लगेगा कि एक लेफ्ट मर्ज डिफ़ॉल्ट रूप से क्यों होगा। मैं और अधिक कहां से सीखूं?
मैथ्यू

7
अच्छा! मैं उपयोग किए जाने वाले सूचकांक-नाम को स्पष्ट रूप से निर्दिष्ट करने से बचने के लिए a.reset_index().merge(b, how="left").set_index(a.index.names)
Truls

3
पंडों ने बुरी तरह से सोचा कि एपीआई फिर से हमला करेगा।
हेनरी हेनरिन्सन

7

आप बाईं डेटाफ़्रेम पर अनुक्रमणिका की प्रतिलिपि बना सकते हैं और मर्ज कर सकते हैं।

a['copy_index'] = a.index
a.merge(b, how='left')

बड़ी डेटाफ्रेम के साथ काम करने और pd.merge_asof()(या dd.merge_asof()) का उपयोग करते हुए मुझे यह सरल विधि बहुत उपयोगी लगी ।

यह तब बेहतर होगा जब इंडेक्स रीसेट करना महंगा हो (बड़ा डेटाफ्रेम)।


1
यह सबसे अच्छा जवाब है। कई कारण हैं कि आप मर्ज के दौरान अपने पुराने अनुक्रमों को संरक्षित करना चाहते हैं (और स्वीकृत जवाब अनुक्रमों को संरक्षित नहीं करता है, यह सिर्फ उन्हें रीसेट करता है)। यह मदद करता है जब आप 2 से अधिक
डेटाफ़्रेम

2
सुपीरियर सॉल्यूशन क्योंकि यह मूल (मूल) इंडेक्स नाम को संरक्षित करता है
मार्तिन लुबेरिंक

उत्कीर्ण लेकिन सिर्फ एक चेतावनी से सावधान रहें, जब मल्टी-इंडेक्स का उपयोग करते हैं, तो आपके सूचकांक को एक एकल कॉलम में एक टुपल के रूप में संग्रहीत किया जाएगा जिसे [copy_index] कहा जाता है
geekidharsh

6

एक गैर pd.merge समाधान है। का उपयोग कर mapऔरset_index

In [1744]: a.assign(col2=a['to_merge_on'].map(b.set_index('to_merge_on')['col2']))
Out[1744]:
   col1  to_merge_on  col2
a     1            1   1.0
b     2            3   2.0
c     3            4   NaN

और, indexइंडेक्स के लिए डमी नाम नहीं देता है ।


1
यह स्वीकृत उत्तर से बेहतर लगता है क्योंकि यह संभवत: मल्टी इंडेक्स जैसे एज मामलों के साथ बेहतर काम करेगा। क्या कोई इस पर टिप्पणी कर सकता है?
बॉलपॉइंटबैन

1
प्रश्न, क्या होगा यदि आपको कई कॉलम असाइन करने की आवश्यकता है, क्या यह दृष्टिकोण काम करेगा या क्या यह केवल 1 फ़ील्ड तक सीमित है?
युका

@ युका: यह संभवतः कई कॉलमों के साथ काम नहीं करेगा, क्योंकि जब आप कई कॉलमों को सब्मिट करते हैं तो आप ए pd.Dataframeऔर ए के साथ समाप्त होते हैं pd.Series.map()विधि केवल के लिए परिभाषित किया गया है pd.Series। इसका मतलब यह है कि: a[['to_merge_on_1', 'to_merge_on_2']].map(...)काम नहीं करेगा।
दातमन

4
df1 = df1.merge(
        df2, how="inner", left_index=True, right_index=True
    )

यह df1 के सूचकांक को संरक्षित करने की अनुमति देता है


यह काम करने लगता है, लेकिन जब मैं इसका उपयोग करता हूं on=list_of_cols], तो यह प्रलेखन का खंडन करता है If joining columns on columns, the DataFrame indexes *will be ignored*:। सूचकांकों बनाम स्तंभों का उपयोग करने में से एक पूर्वता है?
इटाराम काट्ज

0

सोचो मैं एक अलग समाधान के साथ आया हूँ। मैं इंडेक्स वैल्यू पर लेफ्ट टेबल और लेफ्ट टेबल के इंडेक्स के आधार पर कॉलम वैल्यू पर राइट टेबल से जुड़ रहा था। मैंने जो किया वह सामान्य मर्ज था:

First10ReviewsJoined = pd.merge(First10Reviews, df, left_index=True, right_on='Line Number')

फिर मैंने मर्ज किए गए टेबल से नए इंडेक्स नंबरों को पुनः प्राप्त किया और उन्हें सेंटीमेंट लाइन नंबर नामक एक नए कॉलम में डाल दिया।

First10ReviewsJoined['Sentiment Line Number']= First10ReviewsJoined.index.tolist()

तब मैंने मैन्युअल रूप से सूचकांक को पहले से मौजूद मूल, बाएँ तालिका सूचकांक पर वापस सेट कर दिया, जिसे लाइन नंबर से पहले से मौजूद कॉलम कहा जाता है (कॉलम वैल्यू जिसे मैंने लेफ्ट टेबल इंडेक्स से जोड़ा है):

First10ReviewsJoined.set_index('Line Number', inplace=True)

फिर लाइन नंबर का सूचकांक नाम हटा दिया ताकि वह खाली रहे:

First10ReviewsJoined.index.name = None

हो सकता है कि थोड़ा सा हैक हो लेकिन लगता है कि यह अच्छा और अपेक्षाकृत सरल है। इसके अलावा, अनुमान लगाएं कि यह आपके डेटा को डुप्लिकेट / गड़बड़ाने के जोखिम को कम करता है। उम्मीद है कि सभी समझ में आता है।


0

एक और सरल विकल्प सूचकांक का नाम बदलने से पहले था:

a.merge(b, how="left").set_axis(a.index)

मर्ज डेटाफ़्रेम 'ए' में ऑर्डर को संरक्षित करता है, लेकिन बस इंडेक्स को रीसेट करता है इसलिए यह सेट_एक्सिस का उपयोग करने के लिए बचा है

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