2015-05-21 22 views
14

Czy można zapisać tablicę numpy dodając ją do istniejącego pliku npy - coś podobnego do np.save(filename,arr,mode='a')?zapisać tablicę numpy w trybie dopełniającym

Mam kilka funkcji, które mają do iteracji nad wierszami dużej tablicy. Nie mogę utworzyć tablicy naraz ze względu na ograniczenia pamięci. Aby uniknąć wielokrotnego tworzenia wierszy, chciałem utworzyć każdy wiersz tylko raz i zapisać go w pliku, dołączając go do poprzedniego wiersza w pliku. Później mógłbym załadować plik npy ​​w mmap_mode, uzyskując dostęp do plasterków, gdy zajdzie taka potrzeba.

Odpowiedz

8

Wbudowany format pliku .npy doskonale nadaje się do pracy z małymi zestawami danych, bez polegania na modułach zewnętrznych innych niż numpy.

Jednak po rozpoczęciu korzystania z dużych ilości danych preferowane jest użycie formatu pliku, takiego jak HDF5, przeznaczonego do obsługi takich zbiorów danych, [1].

Przykładowo, poniżej znajduje się roztwór zapisać numpy tablic w hdf5 z PyTables,

Etap 1: Tworzenie rozszerzalny EArray przechowywania

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

Etap 2: Dołącz wiersze istniejący zestaw danych (jeśli to konieczne)

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

Krok 3: Czytaj powrotem podzbiór danych

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

dzięki za wskazanie mi PyTables. Bardziej proste podejście z wykorzystaniem klasy Array było wystarczające dla mojego celu. Jestem ciekawy, dlaczego nie ma trybu append dla 'np.save'. Gdyby to było rozsądne, myślę, że zostałoby to wdrożone. – user3820991

+0

Czy to nadal najlepsza metoda w 2018 roku? – Moondra

3

do dopisywania danych do już istniejącego pliku przy użyciu numpy.save powinniśmy używać:

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

mam zaznaczone, że to działa w Pythonie 2.7 i numpy 1.10.4

znalazłem kod here

+3

Właśnie sprawdziłem i nie działa w 'python 2.7.12' i' numpy 1.12.1'. Tablica pozostaje taka sama, nic nie jest dołączone.Zauważ również, że podany link mówi o metodzie 'savetxt', a nie' np.save'. –

+1

Byłem w stanie użyć tego typu układania stosu pomyślnie z Pythona 3.5 i Numpy 1.11.3. Chociaż konieczne było otwarcie pliku w trybie binarnym. – PaxRomana99

0

Plikizawierają nagłówek, który ma kształt i typ dtypu tablicy. Jeśli wiesz, jak wygląda tablica wynikowa, możesz napisać nagłówek, a następnie dane w częściach. Na przykład, tutaj jest kod na łączenie 2d matryc:

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

Jeśli potrzebujesz bardziej ogólne rozwiązanie (Edycja nagłówka w miejscu podczas dołączania) będziesz musiał uciekać się do sztuczek fseek jak w [1].

Zainspirowany
[1]: https://mail.scipy.org/pipermail/numpy-discussion/2009-August/044570.html (nie działa z opakowania)
[2]: https://docs.scipy.org/doc/numpy/neps/npy-format.html
[3]: https://github.com/numpy/numpy/blob/master/numpy/lib/format.py

Powiązane problemy