2017-05-11 12 views
2

多数のNumPy配列をファイル(np.save()、 ".npy"ファイル)として保存したとしましょう。すべてこれらは形状を有する。 (n,20)、私はファイルを開かずにnを知らない。 nはすべてのファイルで異なります。Python - 形状が未知で、メモリに収まらない多数の大きなnumpy配列をマージします。

これらを1つのデータセットにマージし、一連の選択方法を使用して、ディスクに書き込まれた3つの異なるnumpy配列に分割します。

通常、私はすべてのファイルをループし、np.concatenate()を使用します。しかし、最終的な配列はメモリに収まらない可能性があります。

他のオプションはnp.memmap()を使用することです。これはどういう仕組みであるかは絶対に分かりません。私の理解するために、私はそのような何かをする必要があると思います:

a = np.memmap('output.npy',dtype='float64',mode='w+',shape=(N,20)) 
for i,f in enumerate(myfiles): 
    a[i,:] = np.load(f) 
a.flush() 
# And then find a way to split "a" into three, does the following work? 
part_one = a[ [0,2,10,42,58] , : ] 

問題は、私はN、行の最後の番号がわからないということです。したがって、私はmemmapを宣言する前に、各ファイルを開いて、行数を読み込み、ファイルを閉じて、行数を合計する必要があります。これは非常に非効率的であり、より良い方法が必要です。

この問題に関するご意見はありますか?私は何か間違っているのですか?

+0

「行数を読み取る」とは、ヘッダーまたは配列全体を読み取っているだけですか?ちょうどそのヘッダー、それは私にとって妥当と思われる。 – tdelaney

+0

'array.shape()'を使っていますが、これは "header"でしょうか? – Milleuros

+0

... 'np.load'の後に? – tdelaney

答えて

1

.npy file specificationは、npyファイルのヘッダーを定義します。私はすでにそれを読むために焼いた方法を見つけることができませんでしたが、フォーマットは簡単で、あなたは自分自身で情報を引き出すことができます。ファイル情報はshapeタプルを含むpython dictでエンコードされています。これはファイルの先頭を短く読み取ったもので、データを読み込むよりもはるかに高速です。

import struct 
import ast 

# structs to decode .npy file header consisting of a "magic" 
# string verifying the file type, major and minor version numbers, 
# header length, and literal string representation of a python dict 
# holding file's type and shape. 

npy_magic = b"\x93NUMPY" 

npy_v1_header = struct.Struct(
     "<" # little-endian encoding 
     "6s" # 6 byte magic string 
     "B" # 1 byte major number 
     "B" # 1 byte minor number 
     "H" # 2 byte header length 
     # ... header string follows 
) 

npy_v2_header = struct.Struct(
     "<" # little-endian encoding 
     "6s" # 6 byte magic string 
     "B" # 1 byte major number 
     "B" # 1 byte minor number 
     "L" # 4 byte header length 
     # ... header string follows 
) 

def read_npy_file_header(filename): 
    with open(filename, 'rb') as fp: 
     buf = fp.read(npy_v1_header.size) 
     magic, major, minor, hdr_size = npy_v1_header.unpack(buf) 
     if magic != npy_magic: 
      raise IOError("Not an npy file") 
     if major not in (0,1): 
      raise IOError("Unknown npy file version") 
     if major == 2: 
      fp.seek(0) 
      buf = fp.read(npy_v2_header.size) 
      magic, major, minor, hdr_size = npy_v2_header.unpack(buf) 
     return ast.literal_eval(fp.read(hdr_size).decode('ascii')) 


# test 
from glob import glob 
for fn in glob('*.npy'): 
    print(fn, read_npy_file_header(fn)) 
+0

"" \ x93NUMPY "と" <6sBBL "です。それらは何ですか?助けてくれてありがとう! – Milleuros

+0

'struct'モジュールはバイナリデータの読み書きを可能にします。 .npyヘッダーはいくつかのバイナリデータとして定義され、その後に必要な配列情報を保持するPython dictの文字列表現が続きます。 "<6sBBL"はヘッダーのバイナリ部分を読み取り、dict部分がどこにあるかを知る。 '\ x93NUMPY'はこれが本当にnumpyファイルであることを確認するための型検証子です。 – tdelaney

関連する問題