2012-02-19 8 views
14

मेरे पास एक कंप्यूटर पर एक मध्यम आकार की फ़ाइल (4 जीबी सीएसवी) है जिसमें इसे पढ़ने के लिए पर्याप्त रैम नहीं है (64-बिट विंडोज़ पर 8 जीबी)। अतीत में मैंने इसे क्लस्टर नोड पर लोड कर लिया होगा और इसे पढ़ा होगा, लेकिन मेरा नया क्लस्टर मनमाने ढंग से प्रक्रियाओं को 4 जीबी रैम तक सीमित करता है (हार्डवेयर के प्रति 16 जीबी होने के बावजूद), इसलिए मुझे अल्पावधि फिक्स चाहिए ।टुकड़ों में सीएसवी फाइलों में पढ़ने के लिए रणनीतियां?

क्या उपलब्ध स्मृति सीमाओं को फिट करने के लिए आर में एक CSV फ़ाइल के हिस्से में पढ़ने का कोई तरीका है? इस तरह से मैं एक समय में फ़ाइल के एक तिहाई में पढ़ सकता था, इसे पंक्तियों और स्तंभों की आवश्यकता है, और फिर अगले तीसरे में पढ़ा जाए?

कुछ बड़े स्मृति चाल का उपयोग कर कि मैं संभवतः पूरी फ़ाइल में पढ़ सकते हैं ओर इशारा करते हुए के लिए टिप्पणीकर्ताओं के लिए धन्यवाद: Quickly reading very large tables as dataframes in R

मैं कुछ अन्य समाधान के बारे में सोच सकते हैं (एक अच्छा पाठ संपादक में जैसे खुला, 2 बंद कलम/3 अवलोकनों के बाद, आर में लोड), लेकिन यदि संभव हो तो मैं उन्हें बचाना चाहूंगा।

तो इसे टुकड़ों में पढ़ना अभी भी अब के लिए जाने का सबसे अच्छा तरीका है।

+2

इस पर विस्तार से चर्चा की गई है, विशेष रूप से जेडी लॉन्ग का जवाब काफी उपयोगी है: http://stackoverflow.com/questions/1727772/quickly-reading-very-large-tables-as-dataframes-in-r –

+0

एफएफ पैकेज डेटा फ्रेम करता है – mdsumner

+0

क्षमा करें, यह पहला सवाल जवाब देता है। स्पष्ट रूप से मेरे एसओ खोज-फू को सम्मान की जरूरत है, जैसा कि मैंने खोज की थी लेकिन इसे नहीं मिला। यह दूसरे को अनुत्तरित छोड़ देता है, हालांकि: टुकड़ों में सीएसवी फ़ाइल में कैसे पढ़ा जाए। –

उत्तर

8

आप इसे आरएसक्यूलाइट का उपयोग करके डेटाबेस में पढ़ सकते हैं, और फिर एक भाग प्राप्त करने के लिए एक एसक्यूएल कथन का उपयोग कर सकते हैं।

यदि आपको केवल एक ही भाग की आवश्यकता है तो sqldf पैकेज में read.csv.sql डेटा को SQLite डेटाबेस में पढ़ेगा। यह आपके लिए डेटाबेस बनाता है और डेटा आर के माध्यम से नहीं जाता है इसलिए आर की सीमाएं लागू नहीं होंगी। डेटाबेस में इसे पढ़ने के बाद यह आर में निर्दिष्ट एसक्यूएल कथन के आउटपुट को पढ़ता है और फिर डेटाबेस को नष्ट कर देता है। इस पर निर्भर करते हुए कि यह आपके डेटा के साथ कितनी तेजी से काम करता है, यदि आप कई हैं तो आप प्रत्येक भाग के लिए पूरी प्रक्रिया को दोहराने में सक्षम हो सकते हैं।

चूंकि कोड की केवल एक पंक्ति एक ही हिस्से के लिए पूरी चीज करने के लिए है, तो इसे अभी कोशिश करने के लिए कोई ब्रेनर नहीं है। DF <- read.csv.sql("myfile.csv", sql=..., ...other args...)?read.csv.sql और ?sqldf और sqldf home page देखें।

+0

बहुत अच्छा। फिर भी पूरी फ़ाइल में पढ़ने और इसे अधिकतर डंप करने के बावजूद थोड़ा अक्षम लगता है। यह सुझाव देता है कि मैं इसे बस उस राज्य में घटा सकता हूं जिसे मैं एसक्यूएल में चाहता हूं, जो संभवतः मेरी समस्या हल करता है। –

+1

यदि आपको केवल पंक्तियों के एक विशिष्ट सेट पर इसे सब्सक्राइब करने की आवश्यकता है तो आप केवल 'read.table (..., skip = ..., nrows = ...) ' –

+0

का उपयोग कर सकते हैं, मैं इसके बारे में भूल गया था। वाह, वास्तव में एक सवाल असफल दिन है। लेकिन मैंने इस से दो नई चीजें सीखीं ('एफएफ' पैकेज और 'sqldf' दोनों में फ़िल्टर विकल्प है), तो शायद इसके लायक है। –

20

मुझे पता है कि यह एक बहुत पुराना धागा है। हालांकि मैं हाल ही में इस पर आया हूं क्योंकि मुझे एक ही समस्या थी। इस धागे को देखने के बाद मैंने देखा कि इस समस्या का एक विशिष्ट समाधान उल्लेख नहीं किया गया था। कनेक्शन का प्रयोग करें!

1)

read.csv(con, nrows="CHUNK SIZE",...) 

साइड नोट read.csv साथ अपनी फ़ाइल

con = file("file.csv", "r") 

2) कोड की मात्रा में पढ़ने के लिए एक कनेक्शन खोलें: परिभाषित करने colClasses बहुत बातें तेज़ हो जाएगी। अवांछित कॉलम को पूर्ण के रूप में परिभाषित करना सुनिश्चित करें।

3) यदि आप

4) दोहराएँ क्या करने की जरूरत कभी मत करो।

5) कनेक्शन

close(con) 

बंद इस दृष्टिकोण का लाभ कनेक्शन है। यदि आप इस चरण को छोड़ देते हैं, तो यह धीमी चीजों को धीमा कर देगा। मैन्युअल रूप से कनेक्शन खोलकर, आप अनिवार्य रूप से डेटा सेट खोलते हैं और जब तक आप करीबी फ़ंक्शन को कॉल नहीं करते हैं तब तक इसे बंद न करें। इसका मतलब यह है कि जब आप डेटा सेट के माध्यम से लूप करते हैं तो आप कभी भी अपना स्थान नहीं खो देंगे। कल्पना करें कि आपके पास 1e7 पंक्तियों वाला डेटा सेट है। यह भी कल्पना करें कि आप एक समय में 1e5 पंक्तियों का एक हिस्सा लोड करना चाहते हैं।चूंकि हम कनेक्शन खोलते हैं, हमें read.csv(con, nrow=1e5,...) चलाकर पहली 1e5 पंक्तियां मिलती हैं, फिर दूसरा भाग प्राप्त करने के लिए हम read.csv(con, nrow=1e5,...) चलाते हैं, और इसी तरह ...

यदि हमने कनेक्शन का उपयोग नहीं किया तो हम पहले पाएंगे उसी तरह से, read.csv("file.csv", nrow=1e5,...), हालांकि अगले खंड के लिए हमें read.csv("file.csv", skip = 1e5, nrow=2e5,...) की आवश्यकता होगी। स्पष्ट रूप से यह अक्षम है। इस तथ्य के बावजूद कि हम केवल 1e5 पंक्ति में पढ़ते हैं, हमें फिर से 1e5 + 1 पंक्ति मिलनी है।

अंत में, data.table::fread महान है। लेकिन आप इसे कनेक्शन पास नहीं कर सकते हैं। तो यह दृष्टिकोण काम नहीं करता है।

मुझे आशा है कि इससे किसी की मदद मिलेगी।

अद्यतन

लोग इस पोस्ट को upvoting तो मैं मैं एक और संक्षिप्त सोचा जोड़ना होगा सोचा रहते हैं। नया readr::read_csv, जैसे read.csv, कनेक्शन पारित किया जा सकता है। हालांकि, यह advertised लगभग 10x तेज है।

+2

data.table के fread अगले स्थिर रिलीज में कनेक्शन के लिए समर्थन की योजना बनाई है, [data.table # 561] (https://github.com/Rdatatable/data.table/issues/561) – jangorecki

+2

नोट में अधिक जानकारी है कि 'पढ़ * 'iotools' पैकेज के कार्यों को एक कनेक्शन खिलाया जा सकता है। – lmo

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