Numpy配列を保存して、既存のnpyファイルに追加することは可能ですか?--- np.save(filename,arr,mode='a')
のようなものですか?
大きな配列の行を反復処理する必要のある関数がいくつかあります。メモリの制約のため、一度に配列を作成できません。行を何度も作成することを避けるために、各行を一度作成し、ファイルに保存して、ファイルの前の行に追加したいと思いました。後で、必要に応じてスライスにアクセスして、mmap_modeでnpyファイルをロードできました。
ビルドイン.npy
ファイル形式は、numpy
以外の外部モジュールに依存することなく、小さなデータセットを扱うのに最適です。
ただし、大量のデータを取得する場合は、そのようなデータセットを処理するために設計されたHDF5などのファイル形式を使用することをお勧めします [1] 。
たとえば、以下は、HDF5でnumpy
配列を PyTables で保存するためのソリューションです。
ステップ1:拡張可能なものを作成 EArray
storage
import tables
import numpy as np
filename = 'outarray.h5'
ROW_SIZE = 100
NUM_COLUMNS = 200
f = tables.open_file(filename, mode='w')
atom = tables.Float64Atom()
array_c = f.create_earray(f.root, 'data', atom, (0, ROW_SIZE))
for idx in range(NUM_COLUMNS):
x = np.random.Rand(1, ROW_SIZE)
array_c.append(x)
f.close()
ステップ2:既存のデータセットに行を追加する(必要な場合)
f = tables.open_file(filename, mode='a')
f.root.data.append(x)
ステップ3:データのサブセットをリードバックする
f = tables.open_file(filename, mode='r')
print(f.root.data[1:10,2:20]) # e.g. read from disk only this part of the dataset
これは、Mohit Pandeyの回答を拡張したもので、完全な保存/読み込みの例を示しています。 Python 3.6およびNumpy 1.11.3を使用してテストされました。
from pathlib import Path
import numpy as np
import os
p = Path('temp.npy')
with p.open('ab') as f:
np.save(f, np.zeros(2))
np.save(f, np.ones(2))
with p.open('rb') as f:
fsz = os.fstat(f.fileno()).st_size
out = np.load(f)
while f.tell() < fsz:
out = np.vstack((out, np.load(f)))
out = array([[0.、0.]、[1.、1.]])
Numpy.saveを使用して既存のファイルにデータを追加するには、次を使用する必要があります。
f_handle = file(filename, 'a')
numpy.save(f_handle, arr)
f_handle.close()
python 2.7およびnumpy 1.10.4で動作することを確認しました
here のコードを適用しました。これはsavetxtメソッドについて説明しています。
.npy
ファイルには、配列の形状とdtypeを含むヘッダーが含まれています。結果の配列がどのように見えるかがわかっている場合は、ヘッダーを自分で書き、データをチャンクで書き込むことができます。たとえば、2Dマトリックスを連結するためのコードは次のとおりです。
import numpy as np
import numpy.lib.format as fmt
def get_header(fnames):
dtype = None
shape_0 = 0
shape_1 = None
for i, fname in enumerate(fnames):
m = np.load(fname, mmap_mode='r') # mmap so we read only header really fast
if i == 0:
dtype = m.dtype
shape_1 = m.shape[1]
else:
assert m.dtype == dtype
assert m.shape[1] == shape_1
shape_0 += m.shape[0]
return {'descr': fmt.dtype_to_descr(dtype), 'fortran_order': False, 'shape': (shape_0, shape_1)}
def concatenate(res_fname, input_fnames):
header = get_header(input_fnames)
with open(res_fname, 'wb') as f:
fmt.write_array_header_2_0(f, header)
for fname in input_fnames:
m = np.load(fname)
f.write(m.tostring('C'))
より一般的なソリューション(追加中にヘッダーを編集する)が必要な場合は、[1]のようなfseek
トリックに頼る必要があります。
に触発
[1]: https://mail.scipy.org/pipermail/numpy-discussion/2009-August/044570.html (そのままでは機能しません)
[2]: https://docs.scipy.org/doc/numpy/neps/npy-format.html
[3]: https://github.com/numpy/numpy/blob/master/numpy/lib/format.py
あなたはファイルを読んで新しいデータを追加するようなものを試すことができます
import numpy as np
import os.path
x = np.arange(10) #[0 1 2 3 4 5 6 7 8 9]
y = np.load("save.npy") if os.path.isfile("save.npy") else [] #get data if exist
np.save("save.npy",np.append(y,x)) #save the new
2つの操作の後:
print(np.load("save.npy")) #[0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9]