2013-01-09 16 views
11

मैं मैटलैब स्क्रिप्ट को numpy में परिवर्तित कर रहा हूं, लेकिन बाइनरी फ़ाइल से डेटा पढ़ने के साथ कुछ समस्याएं हैं। फ़ाइल की शुरुआत को छोड़ने के लिए fromfile का उपयोग करते समय fseek पर कोई समतुल्य है? यह उन निष्कर्षों का प्रकार है जिन्हें मुझे करने की आवश्यकता है:numpy के साथ बाइनरी फ़ाइल का हिस्सा कैसे पढ़ा जाए?

fid = fopen(fname); 
fseek(fid, 8, 'bof'); 
second = fread(fid, 1, 'schar'); 
fseek(fid, 100, 'bof'); 
total_cycles = fread(fid, 1, 'uint32', 0, 'l'); 
start_cycle = fread(fid, 1, 'uint32', 0, 'l'); 

धन्यवाद!

उत्तर

19

आप सामान्य रूप से फ़ाइल ऑब्जेक्ट के साथ खोज का उपयोग कर सकते हैं और फिर fromfile में इस फ़ाइल ऑब्जेक्ट का उपयोग कर सकते हैं। यहाँ एक पूर्ण उदाहरण है:

import numpy as np 
import os 

data = np.arange(100, dtype=np.int) 
data.tofile("temp") # save the data 

f = open("temp", "rb") # reopen the file 
f.seek(256, os.SEEK_SET) # seek 

x = np.fromfile(f, dtype=np.int) # read the data into numpy 
print x 
# [64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 
# 89 90 91 92 93 94 95 96 97 98 99] 
+1

डैंग, फ़ाइल नाम के बजाय फ़ाइल ऑब्जेक्ट! यह वही है जो मैं ढूंढ रहा हूं, इसे दस्तावेज में जोड़ा जाना चाहिए ... धन्यवाद! – brorfred

3

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

उदाहरण के लिए, chunkyfoo.bin एक फ़ाइल है जिसमें 6-बाइट हेडर, 1024-बाइट numpy सरणी, और एक और 1024-बाइट numpy सरणी शामिल है। आप फ़ाइल को खोल नहीं सकते हैं और 6 बाइट्स खोज सकते हैं (क्योंकि पहली बात numpy.fromfilelseek 0 पर वापस है)। लेकिन तुम सिर्फ mmap फ़ाइल कर सकते हैं और इसके बजाय fromstring का उपयोग करें:

with open('chunkyfoo.bin', 'rb') as f: 
    with closing(mmap.mmap(f.fileno(), length=0, access=mmap.ACCESS_READ)) as m: 
     a1 = np.fromstring(m[6:1030]) 
     a2 = np.fromstring(m[1030:]) 

यह वास्तव में कैसे आप क्या करना चाहते लगता है। बेशक, वास्तविक जीवन में ऑफसेट और लंबाई a1 और a2 शायद निश्चित टिप्पणियों के बजाय शीर्ष पर निर्भर करती है।

हैडर सिर्फ m[:6] है, और आप पार्स कर सकते हैं कि स्पष्ट रूप से यह अलग खींच, struct मॉड्यूल, या जो कुछ भी का उपयोग करके आप एक बार आप read डेटा करना चाहते हैं। लेकिन, यदि आप पसंद करते हैं, आप स्पष्ट रूप से seek और readf से m निर्माण करने से पहले या बाद में, या यहाँ तक कि एक ही कॉल m पर कर सकते हैं, और यह काम करेंगे, a1 और a2 को प्रभावित किए बिना।

एक वैकल्पिक है, जो मैं एक अलग गैर numpy से संबंधित परियोजना के लिए किया है, इस प्रकार एक आवरण फ़ाइल वस्तु बनाने के लिए है:

class SeekedFileWrapper(object): 
    def __init__(self, fileobj): 
     self.fileobj = fileobj 
     self.offset = fileobj.tell() 
    def seek(self, offset, whence=0): 
     if whence == 0: 
      offset += self.offset 
     return self.fileobj.seek(offset, whence) 
    # ... delegate everything else unchanged 

मैं द्वारा "और शेष सभी को अपरिवर्तित प्रतिनिधि" था निर्माण समय पर विशेषताओं के list उत्पन्न करना और __getattr__ में इसका उपयोग करना, लेकिन शायद आप कुछ कम हैकी चाहते हैं। numpy केवल फ़ाइल-जैसी ऑब्जेक्ट के कुछ तरीकों पर निर्भर करता है, और मुझे लगता है कि वे सही तरीके से प्रलेखित हैं, इसलिए बस स्पष्ट रूप से उनको प्रतिनिधि दें। लेकिन मुझे लगता है कि mmap समाधान यहां अधिक समझ में आता है, जब तक कि आप स्पष्ट seek-आधारित कोड के समूह पर यांत्रिक रूप से पोर्ट करने की कोशिश नहीं कर रहे हैं। (आपको लगता है कि mmap आपको numpy.array के बजाय numpy.memmap के रूप में छोड़ने का विकल्प भी देगा, जो numpy को पेजिंग आदि पर अधिक नियंत्रण/प्रतिक्रिया देता है, लेकिन numpy.memmap और mmap प्राप्त करना वास्तव में बहुत मुश्किल है एक साथ काम करने के लिए।)

+1

जो भी इसे कम करता है, उसे समझाने की देखभाल क्यों करें? – abarnert

+0

पुराना धागा, लेकिन फ़ाइल से फ़ाइल स्थिति से fromfile पढ़ता है। इस मशीनरी में से कई अनियंत्रित हैं और numpy.fromfile से धीमे हो जाएंगे। – noobermin

1

यह मैं एक विषम बाइनरी फ़ाइल में मनमाने ढंग से पढ़ने के लिए जब मैं क्या कर रहा है।
Numpy सरणी के dtype को बदलकर आर्बिट्रे तरीके से थोड़ा पैटर्न की व्याख्या करने की अनुमति देता है। प्रश्न में मैटलैब कोड char और दो uint पढ़ता है।

यह paper (वैज्ञानिक स्तर के लिए नहीं, उपयोगकर्ता स्तर पर आसान पढ़ने) को पढ़ें, जो किसी सरणी के प्रकार, घुमावदार, आयाम को बदलने के साथ प्राप्त कर सकता है।

import numpy as np 

data = np.arange(10, dtype=np.int) 
data.tofile('f') 

x = np.fromfile('f', dtype='u1') 
print x.size 
# 40 

second = x[8] 
print 'second', second 
# second 2 

total_cycles = x[8:12] 
print 'total_cycles', total_cycles 
total_cycles.dtype = np.dtype('u4') 
print 'total_cycles', total_cycles 
# total_cycles [2 0 0 0]  !endianness 
# total_cycles [2] 

start_cycle = x[12:16] 
start_cycle.dtype = np.dtype('u4') 
print 'start_cycle', start_cycle 
# start_cycle [3] 

x.dtype = np.dtype('u4') 
print 'x', x 
# x [0 1 2 3 4 5 6 7 8 9] 

x[3] = 423 
print 'start_cycle', start_cycle 
# start_cycle [423] 
संबंधित मुद्दे