पंडों read_csv का उपयोग करते समय मेमोरी त्रुटि


79

मैं कुछ सरल करने की कोशिश कर रहा हूं, एक बड़ी सीएसवी फ़ाइल को पंडों के डेटाफ्रेम में पढ़ना।

data = pandas.read_csv(filepath, header = 0, sep = DELIMITER,skiprows = 2)

कोड या तो के साथ विफल रहता है MemoryError , या बस खत्म कभी नहीं।

टास्क मैनेजर में मेम का उपयोग 506 एमबी पर बंद हो गया और 5 मिनट के बाद बिना किसी बदलाव के और सीपीयू गतिविधि के कारण मैंने इसे बंद कर दिया।

मैं पांडा संस्करण 0.11.0 का उपयोग कर रहा हूं।

मुझे पता है कि फ़ाइल पार्सर के साथ एक मेमोरी समस्या हुआ करती थी, लेकिन http://wesmckinney.com/blog/?p=543 के अनुसार यह तय होना चाहिए था।

जिस फ़ाइल को मैं पढ़ने की कोशिश कर रहा हूं वह 366 एमबी है, ऊपर दिया गया कोड काम करता है अगर मैंने फ़ाइल को कुछ छोटा (25 एमबी) घटा दिया।

यह भी हुआ है कि मुझे एक पॉप मिलता है जो मुझे बताता है कि यह 0x1e0baf93 को संबोधित करने के लिए नहीं लिख सकता है ...

स्टैक ट्रेस:

Traceback (most recent call last):
  File "F:\QA ALM\Python\new WIM data\new WIM data\new_WIM_data.py", line 25, in
 <module>
    wimdata = pandas.read_csv(filepath, header = 0, sep = DELIMITER,skiprows = 2
)
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\io\parsers.py"
, line 401, in parser_f
    return _read(filepath_or_buffer, kwds)
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\io\parsers.py"
, line 216, in _read
    return parser.read()
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\io\parsers.py"
, line 643, in read
    df = DataFrame(col_dict, columns=columns, index=index)
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\core\frame.py"
, line 394, in __init__
    mgr = self._init_dict(data, index, columns, dtype=dtype)
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\core\frame.py"
, line 525, in _init_dict
    dtype=dtype)
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\core\frame.py"
, line 5338, in _arrays_to_mgr
    return create_block_manager_from_arrays(arrays, arr_names, axes)
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\core\internals
.py", line 1820, in create_block_manager_from_arrays
    blocks = form_blocks(arrays, names, axes)
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\core\internals
.py", line 1872, in form_blocks
    float_blocks = _multi_blockify(float_items, items)
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\core\internals
.py", line 1930, in _multi_blockify
    block_items, values = _stack_arrays(list(tup_block), ref_items, dtype)
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\core\internals
.py", line 1962, in _stack_arrays
    stacked = np.empty(shape, dtype=dtype)
MemoryError
Press any key to continue . . .

थोड़ी पृष्ठभूमि - मैं लोगों को यह समझाने की कोशिश कर रहा हूं कि पायथन आर के समान ही कर सकता है। इसके लिए मैं एक आर स्क्रिप्ट को दोहराने की कोशिश कर रहा हूं जो करता है

data <- read.table(paste(INPUTDIR,config[i,]$TOEXTRACT,sep=""), HASHEADER, DELIMITER,skip=2,fill=TRUE)

न केवल उपरोक्त फ़ाइल को ठीक से पढ़ने का प्रबंधन करता है, यह इन फ़ाइलों में से कई को लूप में भी पढ़ता है (और फिर डेटा के साथ कुछ सामान करता है)। यदि पायथन को उस आकार की फ़ाइलों के साथ कोई समस्या है, तो मैं एक हारने वाली लड़ाई लड़ सकता हूं ...


1
निश्चित रूप से पांडा को उस आकार के सीएसवीएस के साथ समस्या नहीं होनी चाहिए। क्या आप इस फ़ाइल को ऑनलाइन पोस्ट करने में सक्षम हैं?
एंडी हेडन

1
आप यह सुनिश्चित nrows=something smallकरने के read_csvलिए भी पास होने का प्रयास कर सकते हैं कि यह फ़ाइल का आकार नहीं है जिससे समस्याएं हो सकती हैं, जो एंडी ने कहा, ऐसा नहीं होना चाहिए।
टॉमएग्सपर्गर

1
यह "विजुअल स्टूडियो, एनाकोंडा और PTVS का उपयोग करके" के साथ कुछ करने के लिए हो सकता है ... शायद नियमित रूप से अजगर में भी कोशिश करें
एंडी हेडन

3
मैंने समस्या को हल करने के लिए निम्नलिखित पाया है: सीएसवी को विखंडू के रूप में पढ़ें csv_chunks = pandas.read_csv(filepath, sep = DELIMITER,skiprows = 1, chunksize = 10000), फिर विखंडू को संक्षिप्त करें df = pandas.concat(chunk for chunk in csv_chunks)। मुझे अभी भी यह जानने में दिलचस्पी है कि इसे एक बार में पढ़ना क्यों काम नहीं करता है, मेरे लिए यह सीएसवी रीडर के साथ एक समस्या जैसा दिखता है।
ऐनी

11
यदि कोई अभी भी इसका अनुसरण कर रहा है, तो मेरे पास अपडेट है। मुझे विश्वास है कि सीएसवी पार्सर ठीक है (और बहुत तेज है), लेकिन डेटा फ्रेम के समय कुछ प्रकार की मेमोरी मुद्दा है। इसका कारण मैं यह मानता हूं: जब मैं chunksize=1000सीएसवी को पढ़ने के लिए हैक का उपयोग करता हूं , और फिर सभी डेटा को एक बड़े डेटाफ्रेम में समेटने की कोशिश करता हूं , यह इस बिंदु पर है कि मेमोरी ऊपर की ओर बढ़ जाती है, आकार की तुलना में लगभग 3-4x मेमोरी फुटप्रिंट। मूल फ़ाइल का। क्या किसी को अंदाजा है कि डेटाफ्रेम क्यों फूट सकता है?
ऐनी

जवाबों:


32

विंडोज मेमोरी लिमिटेशन

विंडोज में 32 बिट संस्करण का उपयोग करते समय मेमोरी त्रुटियों को अजगर के साथ बहुत कुछ होता है। ऐसा इसलिए है क्योंकि 32 बिट प्रक्रिया में डिफ़ॉल्ट रूप से खेलने के लिए केवल 2GB मेमोरी मिलती है

मेमोरी उपयोग को कम करने के लिए ट्रिक्स

यदि आप विंडोज़ में 32 बिट अजगर का उपयोग नहीं कर रहे हैं, लेकिन सीएसवी फ़ाइलों को पढ़ते समय अपनी मेमोरी दक्षता में सुधार करना चाहते हैं, तो एक चाल है।

Pandas.read_csv समारोह कहा जाता है एक विकल्प लेता है dtype। इससे पांडा को पता चल सकता है कि आपके सीएसवी डेटा के अंदर कौन से प्रकार मौजूद हैं।

यह कैसे काम करता है

डिफ़ॉल्ट रूप से, पांडा यह अनुमान लगाने की कोशिश करेगा कि आपकी सीएसवी फ़ाइल में क्या है। यह एक बहुत भारी ऑपरेशन है क्योंकि यह dtype का निर्धारण करते समय, इसे मेमोरी में सभी कच्चे डेटा को ऑब्जेक्ट्स (स्ट्रिंग्स) के रूप में रखना पड़ता है।

उदाहरण

मान लें कि आपका सीएसवी इस तरह दिखता है:

name, age, birthday
Alice, 30, 1985-01-01
Bob, 35, 1980-01-01
Charlie, 25, 1990-01-01

यह उदाहरण बेशक स्मृति में पढ़ने के लिए कोई समस्या नहीं है, लेकिन यह सिर्फ एक उदाहरण है।

यदि पंडों को बिना किसी dtype विकल्प के उक्त csv फ़ाइल को पढ़ना था , तो उम्र को स्मृति में तार के रूप में संग्रहीत किया जाएगा, जब तक कि पांडा ने योग्य अनुमान लगाने के लिए csv फ़ाइल की पर्याप्त पंक्तियाँ नहीं पढ़ ली हों।

मुझे लगता है कि पांडा में डिफ़ॉल्ट dtype का अनुमान लगाने से पहले 1,000,000 पंक्तियों को पढ़ना है।

उपाय

निर्दिष्ट करके dtype={'age':int}.read_csv()वसीयत के विकल्प के रूप में पंडों को पता चलेगा कि उम्र की व्याख्या एक संख्या के रूप में की जानी चाहिए। यह आपको बहुत सारी मेमोरी बचाता है।

भ्रष्ट डेटा के साथ समस्या

हालाँकि, यदि आपकी सीएसवी फ़ाइल दूषित होगी, तो इस तरह:

name, age, birthday
Alice, 30, 1985-01-01
Bob, 35, 1980-01-01
Charlie, 25, 1990-01-01
Dennis, 40+, None-Ur-Bz

तब निर्दिष्ट करने dtype={'age':int}से .read_csv()कमांड टूट जाएगी , क्योंकि यह डाली नहीं जा सकती"40+" इंट में । इसलिए अपने डेटा को ध्यान से देखें!

यहाँ आप देख सकते हैं कि कैसे एक पांडा डेटाफ्रेम की मेमोरी का उपयोग बहुत अधिक होता है जब फ्लोट्स को स्ट्रिंग्स के रूप में रखा जाता है:

इसे स्वयं आज़माएं

df = pd.DataFrame(pd.np.random.choice(['1.0', '0.6666667', '150000.1'],(100000, 10)))
resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
# 224544 (~224 MB)

df = pd.DataFrame(pd.np.random.choice([1.0, 0.6666667, 150000.1],(100000, 10)))
resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
# 79560 (~79 MB)

मैं देख सकता हूं कि यह डेटा को पढ़ने में तेजी कैसे ला सकता है, लेकिन स्मृति में कमी? डेटा प्रकार का अनुमान लगाने के लिए निश्चित रूप से इसे प्रति स्तंभ कुछ स्ट्रिंग-मानों से अधिक स्टोर करने की आवश्यकता नहीं होनी चाहिए? Ie, जब तक कि आपके पास एक bazillion कॉलम नहीं है, या read_csvफ़ंक्शन अविश्वसनीय रूप से कायरता कर रहा है, मुझे बहुत आश्चर्य होगा अगर स्मृति का उपयोग अधिक से अधिक हो।
हेंस ओवेरेन

2
@ हेंसेओवरन डेटा के एक महत्वपूर्ण हिस्से को पढ़ने से पहले डेटा प्रकार का अनुमान नहीं लगाया जा सकता है, अन्यथा आप इसे कई बार बदलने का जोखिम उठाते हैं, जो लागत को ढेर कर देता है। मुझे लगता है कि डिफ़ॉल्ट रूप से पांडा अनुमान लगाने से पहले पहली लाख पंक्तियों को पढ़ता है। मैंने अपने पंडों पर आधारित प्रोडक्ट की मेमोरी प्रोफाइल को 50 गुना कई गुना घटाकर सीएसवी लोड में जोड़ा है।
जुआरिनक्स

1
हम्म, इसके बारे में सोचते हुए, मुझे लगता है कि यह तय करना समस्याग्रस्त हो सकता है कि "3" एक फ्लोट या इंट जा रहा है जब तक कि आप कहीं "2.5" भी नहीं देखते। स्पष्टीकरण के लिए धन्यवाद। मुझे इस बारे में पता नहीं था।
हेंस ओवेरेन

यह सच नहीं है। Dtype के साथ और मेमोरी अधिक महंगी और समय धीमी है। Read_csv में dtype के साथ 6 बार परीक्षण किया गया। आयर्स हैं: ... मेमोरी नो dtype: 12,121,429.333333334 | dtype के साथ मेमोरी: 12,124,160.0 ... 13 बार परीक्षण किए गए समय में, एवरेज हैं: ... समय नहीं dtypes: 2.0494697460761437 | dtypes के साथ समय: 2.100334332539485 ... प्रयुक्त: आयात os आयात psutil प्रक्रिया = psutil.Process (os.getpid ()) प्रिंट (process.memory_info ()) rss: ___Data पंक्तियाँ: तीन अलग-अलग डेटासेट, कॉल 90% से 1.5 मिलियन। ऑब्जेक्ट प्रकार हैं। * स्पष्ट रूप से फ्लोट में स्ट्रिंग प्रकार की तुलना में कम आकार होता है
निकोलोस्मेरपोटिस

@nikolaos_mparoutis सुनिश्चित नहीं हैं कि आप इन परिणामों से कैसे आए। हो सकता है कि आप अपना उत्तर लिखना चाहते हों क्योंकि कोड क्या है और आपकी टिप्पणी में क्या टिप्पणी है, इसका पालन करना कठिन है। मेरा जवाब काफी पुराना है, शायद कुछ बदल गया है।
फायरलैक्सएक्स

6

मेरे पास एक मेमोरी मेमोरी की समस्या थी, जिसमें टैब सीमांकित पाठ फ़ाइल के साधारण पढ़ने में लगभग 1 जीबी का आकार (5.5 मिलियन से अधिक रिकॉर्ड) था और इससे मेमोरी की समस्या हल हो गई problem

df = pd.read_csv(myfile,sep='\t') # didn't work, memory error
df = pd.read_csv(myfile,sep='\t',low_memory=False) # worked fine and in less than 30 seconds

स्पाइडर 3.2.3 पायथन 2.7.13 64 बिट


7
यह काउंटरिनिट्यूएट है जिसे low_memory=Falseकम मेमोरी का उपयोग करना चाहिए ..
गुइलिफ़िक्स

2

मैं अपने लिनक्स बॉक्स पर पंडों का उपयोग करता हूं और कई मेमोरी लीक का सामना करना पड़ा है जो केवल पितरों को गीथूब से क्लोन करने के बाद नवीनतम संस्करण में अपग्रेड करने के बाद हल हो गए हैं।


1

मुझे इस समस्या का सामना तब हुआ जब मैं एक वर्चुअल मशीन में चल रहा था, या किसी और जगह, जहां मेमोरी बहुत सीमित है। इसका पंडों या सुन्न या सीएसवी से कोई लेना-देना नहीं है, लेकिन हमेशा होगा यदि आप अधिक मेमोरी का उपयोग करने की कोशिश करते हैं जैसा कि आप उपयोग करने के लिए बदल रहे हैं, न केवल अजगर में।

आपके पास एकमात्र मौका है जो आपने पहले ही कोशिश की थी, बड़ी चीज़ को छोटे टुकड़ों में विभाजित करने का प्रयास करें जो स्मृति में फिट हो।

अगर आपने कभी अपने आप से पूछा कि MapReduce क्या है, तो आपको खुद ही पता चल जाता है ... MapReduce कई मशीनों पर चूजों को वितरित करने की कोशिश करेगा, आप एक के बाद एक मशीन पर चंकी को संसाधित करने का प्रयास करेंगे।

चंक फ़ाइलों के एकत्रीकरण के साथ आपको जो पता चला है वह वास्तव में एक मुद्दा हो सकता है, हो सकता है कि इस ऑपरेशन में कुछ प्रतिलिपि की आवश्यकता हो ... लेकिन अंत में यह शायद आपको आपकी वर्तमान स्थिति में बचाता है लेकिन अगर आपका सीएसवी थोड़ा बड़ा हो जाता है आप फिर से उस दीवार के खिलाफ दौड़ सकते हैं ...

यह भी हो सकता है, कि पांडा इतना स्मार्ट है, कि यह वास्तव में केवल व्यक्तिगत डेटा को मेमोरी में लोड करता है यदि आप इसके साथ कुछ करते हैं, जैसे कि एक बड़े डीएफ को अवगत कराना?

कई चीजें जो आप आज़मा सकते हैं:

  • एक बार में सभी डेटा लोड न करें, लेकिन टुकड़ों में विभाजित करें
  • जहां तक ​​मुझे पता है, hdf5 इन चंक्सों को स्वचालित रूप से करने में सक्षम है और केवल उस भाग को लोड करता है जिस पर आपका प्रोग्राम वर्तमान में काम करता है
  • देखो अगर प्रकार ठीक हैं, तो एक स्ट्रिंग '0.111111' को एक फ्लोट की तुलना में अधिक मेमोरी की आवश्यकता होती है
  • आपको वास्तव में क्या चाहिए, अगर वहाँ एक स्ट्रिंग के रूप में एड्रेस है, तो आपको संख्यात्मक विश्लेषण के लिए इसकी आवश्यकता नहीं हो सकती है ...
  • एक डेटाबेस आपको केवल उन हिस्सों को जोड़ने और लोड करने में मदद कर सकता है जिनकी आपको वास्तव में आवश्यकता होती है (जैसे केवल 1% सक्रिय उपयोगकर्ता)

1

पंडों के लिए कोई त्रुटि नहीं है 0.12.0 और NumPy 1.8.0।

मैं एक बड़ा DataFrame बनाने और इसे csv फ़ाइल में सहेजने और फिर इसे सफलतापूर्वक पढ़ने में कामयाब रहा हूं। कृपया यहाँ उदाहरण देखें । फ़ाइल का आकार 554 एमबी है (यह 1.1 Gb फ़ाइल के लिए भी काम करता है, और 1.1Gb फ़ाइल का उपयोग 30 सेकंड की आवृत्ति उत्पन्न करने में अधिक समय लेता है)। हालांकि मेरे पास 4Gb की रैम उपलब्ध है।

मेरा सुझाव पंडों को अद्यतन करने का प्रयास है। अन्य चीज जो उपयोगी हो सकती है वह कमांड लाइन से आपकी स्क्रिप्ट को चलाने की कोशिश कर रही है, क्योंकि आर के लिए आप विज़ुअल स्टूडियो का उपयोग नहीं कर रहे हैं (यह पहले से ही आपके प्रश्न में टिप्पणियों में सुझाया गया था), इसलिए इसमें अधिक संसाधन उपलब्ध हैं।


1

मैंने chunksizeबड़ी CSV फ़ाइल पढ़ते समय प्रयास किया

reader = pd.read_csv(filePath,chunksize=1000000,low_memory=False,header=0)

पढ़ी गई अब सूची है। हम readerनए सीएसवी को लिख सकते हैं या लिख ​​सकते हैं या किसी भी ऑपरेशन को कर सकते हैं

for chunk in reader:
    print(newChunk.columns)
    print("Chunk -> File process")
    with open(destination, 'a') as f:
        newChunk.to_csv(f, header=False,sep='\t',index=False)
        print("Chunk appended to the file")

0

इन्हें जोड़ें: रेटिंग = pd.read_csv (..., low_memory = गलत, मैमोरी_मैप = सत्य )

इन दोनों के साथ मेरी स्मृति: इन दोनों के बिना # 319.082.496: # 349.110.272


-1

यद्यपि यह एक समाधान के रूप में इतना अधिक नहीं है, लेकिन मैं उस CSV को JSON (तुच्छ होना चाहिए) और read_jsonइसके बजाय विधि का उपयोग करने में परिवर्तित करने का प्रयास करूँगा - मैं इसे पंडों में sSON JSON / डेटाफ्रेम (100 एमबी का) लिख और पढ़ रहा हूं। किसी भी समस्या के बिना रास्ता।

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