15

matlab スクリプトを numpy に変換していますが、バイナリ ファイルからのデータの読み取りに問題があります。ファイルの先頭をスキップするためfseekに使用する場合と同等のものはありますか? fromfileこれは、私が行う必要がある抽出のタイプです。

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');

ありがとう!

4

4 に答える 4

26

通常の方法でファイル オブジェクトでシークを使用してから、このファイル オブジェクトを で使用できます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]
于 2013-01-09T20:09:26.613 に答える
3

もっと良い答えがあるかもしれません… しかし、私がこの問題に直面したとき、私はすでに別々の部分にアクセスしたいファイルを持っていたので、この問題を簡単に解決することができました。

たとえばchunkyfoo.bin、6 バイトのヘッダー、1024 バイトのnumpy配列、および別の 1024バイトの配列で構成されるファイルがあるとしますnumpy。ファイルを開いて 6 バイトをシークすることはできません (最初に行うことnumpy.fromfilelseek0 に戻るため)。ただし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:])

これはまさにあなたがやりたいことのように聞こえます。もちろん、実際のオフセットと長さは、固定されたコメントではなく、おそらくヘッダーに依存しますa1a2

ヘッダーは単なるm[:6]であり、明示的に引き離したり、structモジュールを使用したり、データを取得したら他のことをしたりすることで、それを解析できreadます。ただし、必要に応じて、 を構築する前に明示的に and を構築seekreadたり、構築した後に、または で同じ呼び出しを行うこともできます。これは、 and に影響を与えることなく機能します。fmma1a2

関連のない別のプロジェクトで行った別の方法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と思います。これにより、ページングなどをより詳細に制御/フィードバックすることができます。ただし、実際には、とを一緒に動作させるのはかなり難しいです。)mmapnumpy.memmapnumpy.arraynumpynumpy.memmapmmap

于 2013-01-09T19:56:13.583 に答える
2

これは、異種のバイナリ ファイルで任意のファイルを読み取る必要がある場合に行うことです。
Numpy では、配列のdtypeを変更することにより、任意の方法でビット パターンを解釈できます。質問のMatlabコードは acharと twoを読み取りますuint

配列のdtype、ストライド、次元を変更することで達成できることについて、この論文(科学者向けではなく、ユーザーレベルで読みやすい)を読んでください。

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]
于 2013-01-09T21:20:14.830 に答える