2015-05-21 46 views
14

Có thể tiết kiệm một mảng NumPy phụ thêm nó vào một NPY-file đã tồn tại --- cái gì đó như np.save(filename,arr,mode='a')?lưu mảng NumPy trong chế độ append

Tôi có một số chức năng mà phải lặp qua các hàng của một mảng lớn. Tôi không thể tạo mảng cùng một lúc vì các ràng buộc về bộ nhớ. Để tránh để tạo ra các hàng hơn và hơn nữa, tôi muốn tạo ra mỗi hàng một lần và lưu nó vào tập tin phụ thêm nó vào dòng trước đó trong file. Sau đó tôi có thể tải tệp npy trong mmap_mode, truy cập vào các lát khi cần thiết.

Trả lời

8

Định dạng tệp dựng sẵn .npy hoàn toàn phù hợp để làm việc với các tập dữ liệu nhỏ, mà không cần dựa vào các mô-đun bên ngoài khác thì numpy.

Tuy nhiên, khi bạn bắt đầu có một lượng lớn dữ liệu, việc sử dụng định dạng tệp, chẳng hạn như HDF5, được thiết kế để xử lý các tập dữ liệu đó, được ưu tiên là [1].

Ví dụ, dưới đây là một giải pháp để tiết kiệm numpy mảng trong HDF5 với PyTables,

Bước 1: Tạo một EArray lưu trữ mở rộng

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() 

Bước 2: Thêm hàng vào một hiện tập dữ liệu (nếu cần)

f = tables.open_file(filename, mode='a') 
f.root.data.append(x) 

Bước 3: Đọc lại một tập hợp con của dữ liệu

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 
+3

nhờ chỉ cho tôi đến PyTables. Một cách tiếp cận đơn giản hơn một chút bằng cách sử dụng lớp Array là đủ cho mục đích của tôi. Tôi tò mò tại sao không có chế độ nối thêm cho 'np.save'. Nếu nó là hợp lý, tôi đoán nó sẽ được thực hiện. – user3820991

+0

Đây có phải là phương pháp tốt nhất vẫn là vào năm 2018? – Moondra

3

Đối với phụ thêm dữ liệu vào một tập tin đã tồn tại sử dụng numpy.save, chúng ta nên sử dụng:

f_handle = file(filename, 'a') 
numpy.save(f_handle, arr) 
f_handle.close() 

Tôi đã kiểm tra rằng nó làm việc trong python 2.7 và numPy 1.10.4

tôi thấy mã here

+3

tôi chỉ kiểm tra và nó không hoạt động trong 'python 2.7.12' và 'NumPy 1.12.1'. Mảng chỉ giữ nguyên, không có gì được nối thêm.Cũng lưu ý rằng liên kết mà bạn cung cấp nói về phương thức 'savetxt' chứ không phải' np.save'. –

+1

Tôi đã có thể sử dụng kiểu xếp chồng này thành công với python 3.5 và numpy 1.11.3. Mặc dù nó là cần thiết để mở tệp ở chế độ nhị phân. – PaxRomana99

0

.npy tập tin chứa tiêu đề có hình dạng và dtype của mảng trong đó. Nếu bạn biết mảng kết quả của bạn trông như thế nào, bạn có thể tự viết tiêu đề và sau đó dữ liệu theo khối. Ví dụ, đây là mã cho concatenating ma trận 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')) 

Nếu bạn cần một giải pháp tổng quát hơn (chỉnh sửa tiêu đề ở chỗ trong khi phụ), bạn sẽ phải nghỉ mát để fseek thủ thuật như trong [1].

Lấy cảm hứng từ
[1]: https://mail.scipy.org/pipermail/numpy-discussion/2009-August/044570.html (không hoạt động ra khỏi hộp)
[2]: https://docs.scipy.org/doc/numpy/neps/npy-format.html
[3]: https://github.com/numpy/numpy/blob/master/numpy/lib/format.py