¿Cuál es la mejor manera de almacenar una x (2 ^ 20) de matriz 16 en MATLAB?
Pregunta
Estoy pensando en escribir los datos en un archivo. ¿Alguien tiene un ejemplo de cómo escribir una gran cantidad de datos en un archivo?
Editar: La mayoría de los elementos de la matriz son ceros, otros son uint32
. Creo que la save()
simple y load()
funcionarían, como se sugiere @Jonas.
Solución
Creo que nadie ha visto la edición de los ceros:)
Si son todo ceros, debe convertir su matriz para su representación escasa y después guardarlo. Usted puede hacer eso con la función escasa .
Código
z = zeros(10000,10000);
z(123,456) = 1;
whos z
z = sparse(z);
whos z
Salida
Name Size Bytes Class Attributes
z 10000x10000 800000000 double
Name Size Bytes Class Attributes
z 10000x10000 40016 double sparse
No creo que la implementación escasa está diseñado para uint32
mango.
Otros consejos
Si está preocupado por mantener el tamaño del archivo de datos lo más pequeño posible, he aquí algunas sugerencias:
- escribir los datos en un archivo binario (es decir, utilizando FWRITE ) en lugar de un archivo de texto (es decir, utilizando fprintf).
- Si los datos contienen todos los valores enteros, o convertirlo a guardarlo como un firmado o tipo entero sin signo en lugar del predeterminado doble tipo de precisión usos de MATLAB.
- Si los datos contienen valores de punto flotante, pero no es necesario el rango o la resolución del defecto tipo de doble precisión , lo convierten en o guardarlo como un solo tipo de precisión .
- Si los datos es suficientemente escasa (es decir, hay muchos más ceros que los no ceros en su matriz), a continuación, puede utilizar la Encuentre función para obtener los índices de fila y columna de los valores distintos de cero, entonces simplemente guardarlas en su archivo.
Aquí hay un par de ejemplos para ilustrar:
data = double(rand(16,2^20) <= 0.00001); %# A large but very sparse matrix
%# Writing the values as type double:
fid = fopen('data_double.dat','w'); %# Open the file
fwrite(fid,size(data),'uint32'); %# Write the matrix size (2 values)
fwrite(fid,data,'double'); %# Write the data as type double
fclose(fid); %# Close the file
%# Writing the values as type uint8:
fid = fopen('data_uint8.dat','w'); %# Open the file
fwrite(fid,size(data),'uint32'); %# Write the matrix size (2 values)
fwrite(fid,data,'uint8'); %# Write the data as type uint8
fclose(fid); %# Close the file
%# Writing out only the non-zero values:
[rowIndex,columnIndex,values] = find(data); %# Get the row and column indices
%# and the non-zero values
fid = fopen('data_sparse.dat','w'); %# Open the file
fwrite(fid,numel(values),'uint32'); %# Write the length of the vectors (1 value)
fwrite(fid,rowIndex,'uint32'); %# Write the row indices
fwrite(fid,columnIndex,'uint32'); %# Write the column indices
fwrite(fid,values,'uint8'); %# Write the non-zero values
fclose(fid); %# Close the file
Los archivos creados anteriormente variará drásticamente en tamaño. El 'data_double.dat'
archivo será de alrededor de 131.073 KB, 'data_uint8.dat'
será de unos 16.385 KB y 'data_sparse.dat'
será menor que 2 KB.
Tenga en cuenta que también he escrito los datos vectoriales \ tamaños de los archivos de modo que los datos pueden ser leídos de nuevo en (usando FREAD ) y formado de nuevo correctamente. Tenga en cuenta también que si yo no proporcionó un argumento 'double'
o 'uint8'
a FWRITE , MATLAB sería lo suficientemente inteligente como para saber que no tenía necesidad de utilizar el doble precisión por defecto y sólo usaría 8 bits para escribir los valores de datos (ya que todos ellos son 0 y 1).
¿Cómo se generan los datos? ¿Cómo se necesita acceder a los datos?
Si calculo correctamente, la variable es inferior a 200 MB si todo es doble. Por lo tanto, usted puede fácilmente guardar y cargar como un solo archivo .mat si necesita acceder a él desde Matlab solamente.
%# create data
data = zeros(16,2^20);
%# save data
save('myFile.mat','data');
%# clear data to test everything works
clear data
%# load data
load('myFile.mat')