NumPy

2013-02-18 54 views
6

के साथ बड़ी स्वरूपित टेक्स्ट फ़ाइल पढ़ना मैंने किसी एक प्रारूप से दूसरे प्रारूप में एक परिमित तत्व जाल को परिवर्तित करने में मदद करने के लिए स्वयंसेवा किया है (i-deas * .unv से अल्बर्टा)। मैंने जाम के कुछ अतिरिक्त आकार देने के लिए NumPy का उपयोग किया है, लेकिन मुझे कच्चे पाठ फ़ाइल डेटा को NumPy arrays में पढ़ने में समस्याएं आ रही हैं। मैंने genfromtxt और loadtxt को अब तक कोई सफलता नहीं मिली है।NumPy

कुछ विवरण:

1) सभी समूहों को उसकी पंक्ति में शीर्ष लेख और पाद झंडा द्वारा सीमांकित कर रहे हैं "-1"।

2) एनओडीई समूह के पास अपनी लाइन पर हेडर "2411" है। मैं केवल 4 समूह के साथ प्रत्येक पंक्ति को छोड़कर, इस समूह से वैकल्पिक लाइनों को पढ़ना चाहता हूं, लेकिन 3 फोरट्रान डबल परिशुद्धता संख्याओं के साथ लाइन को पढ़ना चाहता हूं।

3) तत्व कनेक्टिविटी समूह के पास अपनी लाइन पर हेडर "2412" है। सभी डेटा पूर्णांक हैं और केवल पहले 4 कॉलम पढ़ने की आवश्यकता है। 2 और 3 नोड तत्वों के लिए अनुपलब्ध मानों के कारण NumPy सरणी में कुछ खाली स्लॉट होंगे।

4) "2477" नोड समूह मुझे लगता है कि मैं नियमित अभिव्यक्तियों का उपयोग करके खुद से निपट सकता हूं जो कि कौन सी रेखाएं पढ़ना है।

5) असली डेटा फ़ाइल में टेक्स्ट की लगभग 1 मिलियन लाइनें होंगी, इसलिए यदि संभव हो तो मैं वेक्टरिज्ड होने के लिए बहुत उत्सुक हूं (या जो भी NumPy जल्दी से सामान पढ़ने के लिए करता है)।

क्षमा करें अगर मैंने बहुत अधिक जानकारी दी है, और धन्यवाद।

नीचे दी गई रेखाएं * .unv टेक्स्ट फ़ाइल प्रारूप के हिस्सों का नमूना हैं।

-1 
    2411 
    146303   1   1  11 
    6.9849462399269246D-001 8.0008842847097805D-002 6.6360238055630028D-001 
    146304   1   1  11 
    4.1854795755893875D-001 9.1256034628308313D-001 3.5725496189239300D-002 
    146305   1   1  11 
    7.5541258490349616D-001 3.7870257739063029D-001 2.0504544370783115D-001 
    146306   1   1  11 
    2.7637569971086767D-001 9.2829777518336010D-001 1.3757239038663285D-001 
    -1 
    -1 
2412 
    9  21   1   0   7   2 
    0   0   0 
    1   9 
    10  21   1   0   7   2 
    0   0   0 
    9  10 
    1550  91   6   0   7   3 
    761  3685  2027 
    1551  91   6   0   7   3 
    761  2380  2067 
39720  111   1   0   7   4 
71854  59536  40323  73014 
39721  111   1   0   7   4 
45520  48908 133818 145014 
    -1 
    -1 
    2477 
    1   0   0   0   0   0   0  3022 
PERMANENT GROUP1 
    7   2   0   0   7   3   0   0 
    7   8   0   0   7   7   0   0 
    7  147   0   0   7  148   0   0 
    2   0   0   0   0   0   0  2915 
PERMANENT GROUP2 
    7   1   0   0   7   5   0   0 
    7   4   0   0   7   6   0   0 
    7   9   0   0   7  11   0   0 
    -1 

उत्तर

4

numpy तरीकों genfromtxt और loadtxt, पूरी फ़ाइल पर लागू करने के लिए नहीं बल्कि मुश्किल होगा के रूप में अपने डेटा एक काफी विशेष संरचना (जो के आधार पर बदलता है जो नोड में आप कर रहे हैं) है। इसलिए, मैं निम्नलिखित रणनीति का सुझाव चाहते हैं:

  • लाइनों से फ़ाइल लाइन पढ़ें, निर्धारित करने के लिए लाइन का विश्लेषण करके जो नोड में आप कर रहे हैं की कोशिश करो।

  • यदि आप एक नोड में हैं, जिसमें केवल कुछ डेटा हैं (और जहां, उदाहरण के लिए, आपको वैकल्पिक रेखाएं पढ़नी होंगी, इसलिए आप लगातार पढ़ नहीं सकते हैं), रेखा से लाइन को पढ़ें और लाइनों को संसाधित करें ।

  • जब आप डेटा का एक बहुत कुछ के साथ ("वास्तविक डेटा" के साथ एक तरह) ऐसे भाग तक पहुँचने, numpys fromfile विधि का उपयोग डेटा में पढ़ने के लिए, इस तरह:

    mydata = np.fromfile(fp, sep=" ", dtype=int, count=number_of_elements) 
    mydata.shape = (100000, 3) # Reshape it to the desired shape as fromfile 
               # returns a 1D array. 
    

इस तरह, आप डेटा के बड़े हिस्से को त्वरित रूप से पढ़ने और परिवर्तित करने की क्षमता के साथ लाइन-बाय-लाइन प्रोसेसिंग की लचीलापन को जोड़ते हैं।

अद्यतन: बिंदु यह है कि, आप फ़ाइल खोलते हैं, लाइन से लाइन को पढ़ते हैं, और जब आप डेटा के बड़े हिस्से के साथ किसी स्थान पर पहुंचते हैं, तो आप फाइल डिस्क्रिप्टर को सेफाइल में पास करते हैं।

import numpy as np 

fp = open("test.dat", "r") 
line = fp.readline() 
ndata = int(line.strip()) 
data = np.fromfile(fp, count=ndata, sep=" ", dtype=int) 
fp.close() 

यह एक सामग्री की तरह के साथ एक फ़ाइल test.dat से डेटा पढ़ने जाएगा::

10 
1 2 3 4 5 
6 7 8 9 10 

पहली पंक्ति fp.read() साथ स्पष्ट रूप पढ़ा जाता है, प्रसंस्कृत (संख्या

एक सरल उदाहरण नीचे

पढ़ने के लिए पूर्णांक का निर्धारण किया जाता है) और फिर np.fromfile() डेटा के उचित हिस्से को पढ़ता है और इसे 1 डी-सरणी data में संग्रहीत करता है।

UPDATE2: वैकल्पिक रूप से, आप एक बफर में पूरा पाठ पढ़ सकता है, तो डेटा की बड़ी हिस्सा के लिए प्रारंभ और अंत पदों का निर्धारण और np.fromstring के माध्यम से इसे सीधे परिवर्तित:

fp = open("test.dat", "r") 
txt = fp.read() 
fp.close() 
# Now determine starting and end positions (startpos, endpos) 
# .. 
# pass text that portion of the text to the fromstring function. 
data = np.fromstring(txt[startpos:endpos], dtype=int, sep=" ") 

या, यदि यह है एक नियमित अभिव्यक्ति के रूप में तैयार करना आसान है, आप सीधे फ़ाइल पर fromregex() का उपयोग कर सकते हैं।

+0

आपके सुझावों के लिए धन्यवाद। "सेफाइल" कमांड को देखते हुए यह पहली पंक्ति से फ़ाइल को पढ़ने के लिए प्रतीत होता है, और इसलिए केवल एक विशिष्ट ब्लॉक पढ़ने की अनुमति नहीं देता है। मैंने ऊपर "एफपी" के लिए ब्लॉक को परिभाषित करने के लिए "ओपन" कमांड का उपयोग करने पर देखा, लेकिन यह भी पहली पंक्ति से फ़ाइल को पढ़ने के लिए प्रतीत होता है। – Tim

+0

मैंने ऊपर एक सरलीकृत उदाहरण जोड़ा। –

+0

इसे वर्तनी के लिए धन्यवाद! जिस बिंदु को मैं याद कर रहा था वह था कि रीडलाइन() कमांड सेफाइल कमांड को बताने का असर पड़ता है कि इसे वर्तमान लाइन से एफपी को फ़ाइल की शुरुआत नहीं पढ़नी चाहिए। क्या रीडलाइन() कई बार कॉल किए बिना शुरुआती रेखा को कुछ मूल्य पर सेट करने का कोई तरीका है? मैं लाइन की शुरुआत में स्ट्रिंग "-1" की खोज करके डेटा ब्लॉक की शुरुआत और अंत में लाइन नंबरों को जल्दी से ढूंढ सकता हूं, लेकिन आवश्यक प्रारंभिक बिंदु पर जाने के लिए लूप में रीडलाइन() को कॉल करना होगा कुछ हद तक धीमी चीजें। धन्यवाद! – Tim