2015-10-07 6 views
7

मैं एक डेटाफ्रेम से सभी पंक्तियों को एक अन्य डेटाफ्रेम (एक ही इंडेक्स और कॉलम संरचना वाले डेटाफ्रेम) में जोड़ने के लिए एक शानदार तरीका ढूंढ रहा हूं, लेकिन ऐसे मामलों में जहां डेटाफ्रेम दोनों में समान इंडेक्स मान दिखाई देता है, तो पंक्ति का उपयोग करें दूसरा डेटा फ्रेम।पांडा डेटाफ्रेम संक्षिप्त/अद्यतन ("अपरर्ट")?

तो, उदाहरण के लिए, मैं के साथ शुरू करता है, तो:

df1: 
        A  B 
    date 
    '2015-10-01' 'A1' 'B1' 
    '2015-10-02' 'A2' 'B2' 
    '2015-10-03' 'A3' 'B3' 

df2: 
    date   A  B 
    '2015-10-02' 'a1' 'b1' 
    '2015-10-03' 'a2' 'b2' 
    '2015-10-04' 'a3' 'b3' 

मैं परिणाम चाहते हैं होने के लिए:

    A  B 
    date 
    '2015-10-01' 'A1' 'B1' 
    '2015-10-02' 'a1' 'b1' 
    '2015-10-03' 'a2' 'b2' 
    '2015-10-04' 'a3' 'b3' 

यह है कि मैं क्या लगता है कि कुछ में "Upsert" कहा जाता है के अनुरूप है एसक्यूएल सिस्टम --- अद्यतन और सम्मिलन का संयोजन, इस अर्थ में कि df2 से प्रत्येक पंक्ति या तो (ए) df1 में मौजूदा पंक्ति को अद्यतन करने के लिए प्रयोग की जाती है यदि पंक्ति कुंजी df1 में पहले से मौजूद है, या (बी) df1 पर डाली गई है अंत अगर पंक्ति कुंजी पहले से मौजूद नहीं है।

मैं के साथ आए हैं निम्नलिखित

pd.concat([df1, df2])  # concat the two DataFrames 
    .reset_index()  # turn 'date' into a regular column 
    .groupby('date')  # group rows by values in the 'date' column 
    .tail(1)    # take the last row in each group 
    .set_index('date') # restore 'date' as the index 

जो काम करने के लिए लगता है, लेकिन इस में प्रत्येक GroupBy समूह हमेशा मूल DataFrames, जो मैं नहीं है के रूप में ही किया जा रहा पंक्तियों का क्रम पर निर्भर करता है पर जाँच की, और नापसंद रूप से convoluted लगता है।

क्या किसी के पास अधिक सरल समाधान के लिए कोई विचार है?

उत्तर

10

एक समाधान df1 को df2 में नई पंक्तियों के साथ जोड़ना है (यानी जहां सूचकांक मेल नहीं खाता है)। फिर df2 से उन मानों को अपडेट करें।

df = pd.concat([df1, df2[~df2.index.isin(df1.index)]]) 
df.update(df2) 

>>> df 
      A B 
2015-10-01 A1 B1 
2015-10-02 a1 b1 
2015-10-03 a2 b2 
2015-10-04 a3 b3 

संपादित करें: @chrisb के सुझाव के अनुसार, इस आगे इस प्रकार सरल किया जा सकता:

pd.concat([df1[~df1.index.isin(df2.index)], df2]) 

धन्यवाद क्रिस!

+0

अच्छा। मैं दक्षता के बारे में भी सोच रहा हूं। यह दृष्टिकोण निश्चित रूप से मेरे समूह समाधान से अधिक कुशल लगता है, लेकिन ऐसा लगता है कि यह अभी भी डीएफ 1 और डीएफ 2 दोनों में डेटा को पार करने में शामिल होगा (पैंडस को आंतरिक रूप से क्या करना है, मेरा मतलब है)। अगर किसी के पास एक और अधिक कुशल दृष्टिकोण के बारे में विचार है, तो मुझे उन्हें सुनना अच्छा लगेगा! – embeepea

+2

आप रिवर्स ऑर्डर में लिखकर अपडेट से बच सकते हैं; 'pd.concat ([df1 [~ df1.index.isin (df2.index)], df2])' – chrisb

+2

@embeepea अच्छी तरह से वाईएमएमवी। लेकिन यह वास्तव में काफी कुशल है, इसमें एक सेट सेशन (इंडेक्स पर) और 1 ले (इंडेक्सिंग), और एक कॉपी (कॉन्सट) शामिल है। उदाहरण के लिए। 1 एमएम पंक्तियां, मेरी मशीन पर 150 मिलीमीटर लेती हैं। – Jeff

संबंधित मुद्दे