पांडस मर्ज - डुप्लिकेट कॉलम से कैसे बचें


96

मैं दो डेटा फ़्रेम के बीच मर्ज करने का प्रयास कर रहा हूं। प्रत्येक डेटा फ़्रेम में दो सूचकांक स्तर (दिनांक, क्यूसिप) होते हैं। कॉलम में, कुछ कॉलम उदाहरण के लिए दोनों (मुद्रा, adj तारीख) के बीच मेल खाते हैं।

इंडेक्स द्वारा इनका विलय करने का सबसे अच्छा तरीका क्या है, लेकिन मुद्रा और adj तारीख की दो प्रतियां नहीं लेना है।

प्रत्येक डेटा फ़्रेम 90 कॉलम है, इसलिए मैं हाथ से सब कुछ लिखने से बचने की कोशिश कर रहा हूं।

df:                 currency  adj_date   data_col1 ...
date        cusip
2012-01-01  XSDP      USD      2012-01-03   0.45
...

df2:                currency  adj_date   data_col2 ...
date        cusip
2012-01-01  XSDP      USD      2012-01-03   0.45
...

यदि मैं करता हूँ:

dfNew = merge(df, df2, left_index=True, right_index=True, how='outer')

मुझे मिला

dfNew:              currency_x  adj_date_x   data_col2 ... currency_y adj_date_y
date        cusip
2012-01-01  XSDP      USD      2012-01-03   0.45             USD         2012-01-03

धन्यवाद! ...

जवाबों:


149

आप उन स्तंभों को काम कर सकते हैं जो केवल एक DataFrame में हैं और मर्ज में स्तंभों के सबसेट का चयन करने के लिए इसका उपयोग करते हैं।

cols_to_use = df2.columns.difference(df.columns)

फिर मर्ज करें (ध्यान दें कि यह एक इंडेक्स ऑब्जेक्ट है लेकिन इसकी एक आसान tolist()विधि है)।

dfNew = merge(df, df2[cols_to_use], left_index=True, right_index=True, how='outer')

यह किसी भी कॉलम को मर्ज में फंसने से बचाएगा।


4
क्या होगा यदि कुंजी एक कॉलम है और इसे समान कहा जाता है? इसे पहले कदम के साथ गिराया जाएगा।
गुएरा

94

मैं इस suffixesविकल्प का उपयोग करता हूं .merge():

dfNew = df.merge(df2, left_index=True, right_index=True,
                 how='outer', suffixes=('', '_y'))
dfNew.drop(dfNew.filter(regex='_y$').columns.tolist(),axis=1, inplace=True)

धन्यवाद @ जीजाजी


18
अधिक उपयोगी उत्तर होगा यदि इसमें कोड के लिए filterआईएनजी शामिल है (जो कि काफी सरल है, फिर भी देखने के लिए समय लेने वाली / त्रुटि-प्रवण है)। यानी dfNew.drop(list(dfNew.filter(regex='_y$')), axis=1, inplace=True)
२०:२ph बजे आईजोसफ

6

@ Rprog के उत्तर पर बिल्डिंग, आप प्रत्यय के विभिन्न टुकड़ों को मिला सकते हैं और एक नेगेटिव रेक्सक्स का उपयोग करके चरण को एक लाइन में फ़िल्टर कर सकते हैं:

dfNew = df.merge(df2, left_index=True, right_index=True,
             how='outer', suffixes=('', '_DROP')).filter(regex='^(?!.*_DROP)')

या उपयोग कर रहा है df.join:

dfNew = df.join(df2, lsuffix="DROP").filter(regex="^(?!.*DROP)")

यहां रेक्सक्स कुछ भी रख रहा है जो शब्द "डीआरओपी" के साथ समाप्त नहीं होता है , इसलिए बस एक प्रत्यय का उपयोग करना सुनिश्चित करें जो पहले से ही कॉलम के बीच प्रकट नहीं होता है।


5

मैं पंडों के साथ नया हूँ, लेकिन मैं वही चीज़ हासिल करना चाहता था, जो स्वचालित रूप से _x या _y के साथ कॉलम नामों से परहेज करता है और डुप्लिकेट डेटा को हटाता है। मैंने आखिरकार इस जवाब का उपयोग करके किया और स्टैकओवरफ्लो से यह एक

sales.csv

    शहर, राज्य, इकाइयों
    Mendocino; CA; 1
    डेनवर, सीओ, 4
    ऑस्टिन, टेक्सास, 2

revenue.csv

    branch_id शहर, राजस्व, state_id
    10; ऑस्टिन, 100, TX
    20; ऑस्टिन; 83; TX
    30; ऑस्टिन, 4, टेक्सास
    47; ऑस्टिन, 200, TX
    20; डेनवर, 83, सीओ
    30; स्प्रिंगफील्ड, 4, मैं

मर्जडोमैक्स आयात पांडा

def drop_y(df):
    # list comprehension of the cols that end with '_y'
    to_drop = [x for x in df if x.endswith('_y')]
    df.drop(to_drop, axis=1, inplace=True)


sales = pandas.read_csv('data/sales.csv', delimiter=';')
revenue = pandas.read_csv('data/revenue.csv', delimiter=';')

result = pandas.merge(sales, revenue,  how='inner', left_on=['state'], right_on=['state_id'], suffixes=('', '_y'))
drop_y(result)
result.to_csv('results/output.csv', index=True, index_label='id', sep=';')

मर्ज कमांड निष्पादित करते समय मैं _xप्रत्यय को एक रिक्त स्ट्रिंग के साथ प्रतिस्थापित करता हूं और उन्हें मैं समाप्त होने वाले कॉलम को हटा सकता हूं_y

output.csv

    आईडी, शहर, राज्य, इकाइयों, branch_id; राजस्व; state_id
    0; डेनवर, सीओ, 4, 20, 83, सीओ
    1; ऑस्टिन, टेक्सास, 2, 10, 100, TX
    2; ऑस्टिन, टेक्सास; 2; 20; 83; TX
    3; ऑस्टिन, टेक्सास, 2, 30, 4, टेक्सास
    4; ऑस्टिन, टेक्सास, 2, 47, 200, TX

0

यह समस्या के आसपास जाने का एक सा है, लेकिन मैंने एक फ़ंक्शन लिखा है जो मूल रूप से अतिरिक्त कॉलम से संबंधित है:

def merge_fix_cols(df_company,df_product,uniqueID):
    
    df_merged = pd.merge(df_company,
                         df_product,
                         how='left',left_on=uniqueID,right_on=uniqueID)    
    for col in df_merged:
        if col.endswith('_x'):
            df_merged.rename(columns = lambda col:col.rstrip('_x'),inplace=True)
        elif col.endswith('_y'):
            to_drop = [col for col in df_merged if col.endswith('_y')]
            df_merged.drop(to_drop,axis=1,inplace=True)
        else:
            pass
    return df_merged

मेरे मर्ज के साथ अच्छा काम करने लगता है!


0

आप पहले या तो df में कॉलम को सब्मिट नहीं कर सकते?

[अगर मैं df2.columns में नहीं हूं तो मैं df.columns में i]

dfNew = मर्ज (df [i for i for df.columns में अगर मैं df2.columns में नहीं] , df2, left_index = True, right_index = True, how = 'external')

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