2013-06-19 8 views
10

में पांडा के साथ बड़े विलय पर मेमोरी एरर मैं outer करने के लिए पांडा का उपयोग कर रहा हूं ~ 1000-2000 सीएसवी फाइलों के सेट पर विलय। प्रत्येक सीएसवी फ़ाइल में एक पहचानकर्ता कॉलम id होता है जो सभी सीएसवी फाइलों के बीच साझा किया जाता है, लेकिन प्रत्येक फ़ाइल में 3-5 कॉलम के कॉलम का एक अनूठा सेट होता है। प्रत्येक फ़ाइल में लगभग 20,000 अद्वितीय id पंक्तियां हैं। मैं बस इतना करना चाहता हूं कि सभी नए कॉलम एक साथ लाएं और मर्ज इंडेक्स के रूप में id कॉलम का उपयोग करें।पाइथन

मैं यह एक साधारण merge कॉल का उपयोग कर कार्य करें:

merged_df = first_df # first csv file dataframe 
for next_filename in filenames: 
    # load up the next df 
    # ... 
    merged_df = merged_df.merge(next_df, on=["id"], how="outer") 

समस्या यह है कि लगभग 2000 CSV फ़ाइलों के साथ, मैं merge आपरेशन पांडा द्वारा फेंका में एक MemoryError मिलता है। मुझे यकीन नहीं है कि मर्ज ऑपरेशन में किसी समस्या के कारण यह एक सीमा है?

अंतिम डेटाफ्रेम में 20,000 पंक्तियां और मोटे तौर पर (2000 x 3) = 6000 कॉलम होंगे। यह बड़ा है, लेकिन कंप्यूटर पर सभी मेमोरी का उपभोग करने के लिए पर्याप्त नहीं है जिसका उपयोग मैं कर रहा हूं जिसमें 20 जीबी रैम है। क्या यह आकार पांडा मैनिप्ल्यूशन के लिए बहुत अधिक है? क्या मुझे इसके बजाय स्क्लाइट की तरह कुछ उपयोग करना चाहिए? क्या इस पैमाने पर काम करने के लिए merge ऑपरेशन में कुछ ऐसा बदल सकता है?

धन्यवाद।

उत्तर

7

मुझे लगता है कि आप एक concat (जो एक बाहरी की तरह कार्य करता शामिल होने) का उपयोग कर बेहतर प्रदर्शन प्राप्त होगा:

dfs = (pd.read_csv(filename).set_index('id') for filename in filenames) 
merged_df = pd.concat(dfs, axis=1) 

इसका मतलब है आप केवल एक ही मर्ज आपरेशन के बजाय प्रत्येक फ़ाइल के लिए एक कर रहे हैं।

+1

स्मृति के रूप में, आप एक जनरल एक्सप्रेशन का उपयोग कर के बजाय होना चाहिए सूची समझ ... (हालांकि 'concat' के आंतरिक कार्यों के बारे में निश्चित नहीं है) – root

+0

@ अच्छी तरह से, जनरेटर केवल बेहतर हो सकता है मुझे लगता है (सबसे खराब मामला यह सिर्फ एक सूची में परिवर्तित हो जाता है) :) –

+0

@root अच्छा स्थान btw ! (टीबी मुझे नहीं पता था कि एक जनरेटर स्वीकार करेगा!) –

0

मैं 1 जीबी फ़ाइल के साथ read_csv का उपयोग कर 32-बिट pytwhen में एक ही त्रुटि से मिला। 64-बिट संस्करण का प्रयास करें और आशा है कि मेमोरी त्रुटि समस्या

0

pd.concat बड़े डेटाफ्रेम के लिए स्मृति से बाहर निकलता प्रतीत होता है, तो एक विकल्प dfs को मैट्रिक्स में परिवर्तित करना और इन्हें सम्मिलित करना है।

def concat_df_by_np(df1,df2): 
    """ 
    accepts two dataframes, converts each to a matrix, concats them horizontally and 
    uses the index of the first dataframe. This is not a concat by index but simply by 
    position, therefore the index of both dataframes should be the same 
    """ 
    dfout = deepcopy(pd.DataFrame(np.concatenate((df1.as_matrix(),df2.as_matrix()),axis=1), 
            index = df1.index, 
            columns = np.concatenate([df1.columns,df2.columns]))) 
    if (df1.index!=df2.index).any(): 
     #logging.warning('Indices in concat_df_by_np are not the same')      
     print ('Indices in concat_df_by_np are not the same')      


    return dfout 

हालांकि, एक के रूप में इस कार्य नहीं है सावधान रहने की जरूरत है एक में शामिल होने बल्कि एक क्षैतिज संलग्न करते हुए जहां सूचकांक अनदेखी कर रहे हैं