¿Es posible np.concatenate archivos asignados en memoria?

Guardé un par de matrices numpy con np.save (), y las armé bastante enormes.

¿Es posible cargarlos todos como archivos asignados en memoria, y luego concatenarlos y dividirlos sin tener que cargarlos en la memoria?

El uso de numpy.concatenate aparentemente carga los arreglos en la memoria. Para evitar esto, puede crear fácilmente una matriz de memmap en un archivo nuevo y leer los valores de las matrices que desea concatenar. De una manera más eficiente, también puede agregar nuevos arreglos a un archivo ya existente en el disco.

En cualquier caso, debe elegir el orden correcto para la matriz (row-major o column-major).

Los siguientes ejemplos ilustran cómo concatenar a lo largo del eje 0 y el eje 1.


1) concatenar a lo largo del axis=0

 a = np.memmap('a.array', dtype='float64', mode='w+', shape=( 5000,1000)) # 38.1MB a[:,:] = 111 b = np.memmap('b.array', dtype='float64', mode='w+', shape=(15000,1000)) # 114 MB b[:,:] = 222 

Puede definir una tercera matriz que lea el mismo archivo que la primera matriz a concatenar (aquí a ) en el modo r+ (leer y adjuntar), pero con la forma de la matriz final que desea obtener después de la concatenación, como:

 c = np.memmap('a.array', dtype='float64', mode='r+', shape=(20000,1000), order='C') c[5000:,:] = b 

La concatenación a lo largo del axis=0 no requiere pasar el order='C' porque ya es el orden predeterminado.


2) concatenar a lo largo del axis=1

 a = np.memmap('a.array', dtype='float64', mode='w+', shape=(5000,3000)) # 114 MB a[:,:] = 111 b = np.memmap('b.array', dtype='float64', mode='w+', shape=(5000,1000)) # 38.1MB b[:,:] = 222 

Los arreglos guardados en el disco en realidad se aplanan, por lo que si crea c con mode=r+ y shape=(5000,4000) sin cambiar el orden del arreglo, los 1000 primeros elementos de la segunda línea en a irán al primer en línea en c . Pero puede evitar fácilmente este order='F' paso order='F' (columna-mayor) para memmap :

 c = np.memmap('a.array', dtype='float64', mode='r+',shape=(5000,4000), order='F') c[:, 3000:] = b 

Aquí tiene un archivo actualizado ‘a.array’ con el resultado de la concatenación. Puede repetir este proceso para concatenar en pares de dos.

Preguntas relacionadas:

  • Trabajando con big data en python y numpy, no hay suficiente ram, ¿cómo guardar resultados parciales en el disco?

Si u usa order='F' , habrá otro problema que, cuando cargue el archivo la próxima vez, se solucionará un problema, incluso pasará el order='F Así que mi solución está abajo, tengo muchas pruebas, simplemente funciona bien.

 fp = your old memmap... shape = fp.shape data = your ndarray... data_shape = data.shape concat_shape = data_shape[:-1] + (data_shape[-1] + shape[-1],) print('cancat shape:{}'.format(concat_shape)) new_fp = np.memmap(new_file_name, dtype='float32', mode='r+', shape=concat_shape) if len(concat_shape) == 1: new_fp[:shape[0]] = fp[:] new_fp[shape[0]:] = data[:] if len(concat_shape) == 2: new_fp[:, :shape[-1]] = fp[:] new_fp[:, shape[-1]:] = data[:] elif len(concat_shape) == 3: new_fp[:, :, :shape[-1]] = fp[:] new_fp[:, :, shape[-1]:] = data[:] fp = new_fp fp.flush()