2012-09-22 11 views
5

मेरा मुख्य लक्ष्य फ़्लोट्स के विशाल मैट्रिक्स से औसत (कॉलम द्वारा) की गणना करना है। उदाहरण:पायथन - फ़ाइल से कॉलम इटरेटर प्राप्त करें (पूरी फ़ाइल को पढ़ने के बिना)

a = numpy.array(([1,1,3,2,7],[4,5,8,2,3],[1,6,9,3,2])) 

numpy.median(a, axis=0) 

Out[38]: array([ 1., 5., 8., 2., 3.]) 

मैट्रिक्स पायथन स्मृति (~ 5 टेराबाइट) में फिट करने के लिए बहुत बड़ा है, तो मैं इसे एक csv फ़ाइल में रहते हैं। तो मैं प्रत्येक कॉलम पर दौड़ना चाहता हूं और औसत की गणना करना चाहता हूं।

क्या मेरे पास पूरी फ़ाइल पढ़ने के बिना कॉलम इटरेटर प्राप्त करने का कोई तरीका है?

मैट्रिक्स के लिए औसत की गणना करने के बारे में कोई अन्य विचार भी अच्छा होगा। धन्यवाद!

+2

यह भी देखें: http://stackoverflow.com/questions/1053928/python-numpy-very-large-matrices –

उत्तर

1

मैं एन खाली फ़ाइलों को शुरू करके ऐसा करता हूं, प्रत्येक कॉलम के लिए एक। फिर एक समय में मैट्रिक्स एक पंक्ति पढ़ें और प्रत्येक कॉलम प्रविष्टि को सही फ़ाइल में भेजें। एक बार जब आप पूरे मैट्रिक्स को संसाधित कर लेते हैं, तो वापस जाएं और अनुक्रमिक रूप से प्रत्येक फ़ाइल के औसत की गणना करें।

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

+1

आपकी प्रतिक्रिया के लिए धन्यवाद!मेरा मैट्रिक्स आकार ~ 5 टेराबाइट्स है, मुझे डर है कि मेरे पास ऐसा करने के लिए पर्याप्त संग्रहण नहीं है :( – dbaron

3

आप स्मृति में प्रत्येक स्तंभ (जो आप मतलब है आप कर सकते हैं लगता है) फिट कर सकते हैं, तो यह काम करना चाहिए:

import itertools 
import csv 

def columns(file_name): 
    with open(file_name) as file: 
     data = csv.reader(file) 
     columns = len(next(data)) 
    for column in range(columns): 
     with open(file_name) as file: 
      data = csv.reader(file) 
      yield [row[column] for row in data] 

यह जानने हम कितने कॉलम से काम करता है, तो फ़ाइल पर पाशन , मौजूदा पंक्ति के आइटम को प्रत्येक पंक्ति से बाहर ले जाना। इसका मतलब है, सबसे अधिक, हम एक कॉलम के आकार और एक समय में स्मृति की पंक्ति के आकार का उपयोग कर रहे हैं। यह एक बहुत ही सरल जनरेटर है। ध्यान दें कि हमें फ़ाइल को फिर से खोलना होगा, क्योंकि जब हम इसके माध्यम से लूप करते हैं तो हम इटेटरेटर को निकाल देते हैं।

+0

यदि फ़ाइल को फिर से खोलना एक समस्या है, तो बस लूप के बाहर 'साथ' को ले जाएं और 'file.seek' करें (0) 'अंदर। –

+0

@MuMind यह बार-बार फिर से खोलने का एक अच्छा विकल्प है (और इसका मतलब यह भी होगा कि यदि आपके पास किसी भी कारण से फ़ाइल नाम नहीं है तो आप फ़ाइल ऑब्जेक्ट पास कर सकते हैं) –

0

आप डिस्क पर प्रत्येक कॉलम को स्मृति में पढ़ने के बिना बाल्टीसेट का उपयोग कर सकते हैं। फिर आप केवल मध्यम मूल्य चुन सकते हैं।

या आप UNIX awk और sort आदेशों को विभाजित करने के लिए उपयोग कर सकते हैं और फिर मध्यस्थ का चयन करने से पहले अपने कॉलम को सॉर्ट कर सकते हैं।

1

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

>>> import csv 
>>> with open('foo.csv', 'wb') as f: 
...  writer = csv.writer(f) 
...  for i in range(0, 100, 10): 
...   writer.writerow(range(i, i + 10)) 
... 
>>> with open('foo.csv', 'r') as f: 
...  f.read() 
... 
'0,1,2,3,4,5,6,7,8,9\r\n10,11,12,13,14,15,16,17,18,19\r\n20..(output truncated).. 

आप देख सकते हैं, एक स्तंभ फ़ील्ड जाहिर नहीं मिलाया गया है, दूसरा कॉलम इंडेक्स 2 पर शुरू होता है, लेकिन फिर अगली पंक्ति में, कॉलम की चौड़ाई एक से बढ़ जाती है, संरेखण को फेंक देती है। इनपुट की लंबाई अलग होने पर यह भी बदतर है। उपरोक्त यह है कि सीएसवी पाठक को उस डेटा को फेंकने के लिए पूरी फ़ाइल को पढ़ना होगा, जिसका आप उपयोग नहीं करते हैं। (यदि आपको यह बुरा नहीं लगता है, तो यह जवाब है - उस डेटा को फेंकने के लिए, जो आप उपयोग नहीं करेंगे, उसे फेंक दें।)

यदि आपको कुछ जगह बर्बाद करने की कोई बात नहीं है और उसे पता है आपका कोई भी डेटा कुछ निश्चित चौड़ाई से अधिक नहीं होगा, आप निश्चित-चौड़ाई वाले फ़ील्ड वाली फ़ाइल बना सकते हैं, और फिर आप ऑफ़सेट का उपयोग कर इसे खोज सकते हैं। लेकिन फिर, एक बार ऐसा करने के बाद, आप एक असली डेटाबेस का उपयोग शुरू कर सकते हैं। PyTables numpy arrays को संग्रहीत करने के लिए कई लोगों की पसंदीदा पसंद प्रतीत होता है।

+1

+1 यदि आप जा रहे हैं इसे एक से अधिक बार करने के लिए, सीएसवी इसे रखने के लिए प्रारूप की खराब पसंद है। –

+0

@ सेंडर डीबी मेरा लक्ष्य है। क्या आपको पता है कि numpy.loadtxt (file_path, usecols = [1,2,3]) करेगा अब के लिए चाल? – dbaron

+0

@ डबरन, यह सिर्फ "चाल चलाना" से आपका मतलब है पर निर्भर करता है। मुझे पूरा यकीन है कि 'usecols = [1, 2, 3]' पूरे मैट्रिक्स को स्मृति में एक बार में लोड करने से बचना होगा , तो उस अर्थ में, हां। मुझे भी यकीन है कि यह पूरी फ़ाइल _ लाइन_ लाइन से लाइन करेगा, अप्रयुक्त डेटा फेंक देगा, इसलिए उसमें एनएसई, नहीं। – senderle

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

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