Как лучше всего хранить матрицу размером 16 × (2 ^ 20) в MATLAB?
Вопрос
Я думаю записать данные в файл.Есть ли у кого-нибудь пример того, как записать большой объем данных в файл?
Редактировать: Большинство элементов матрицы — нули, остальные — нули. uint32
.Я думаю, самое простое save()
и load()
будет работать, как предложил @Jonas.
Решение
Я думаю, никто не видел редактировать о Zeroes :)
Если они в основном нули, вы должны преобразовать вашу матрицу в его редкое представление и тогда сохрани это. Вы можете сделать это с редкий функция.
Код
z = zeros(10000,10000);
z(123,456) = 1;
whos z
z = sparse(z);
whos z
Выход
Name Size Bytes Class Attributes
z 10000x10000 800000000 double
Name Size Bytes Class Attributes
z 10000x10000 40016 double sparse
Я не думаю, что редкая реализация предназначена для обработки uint32
.
Другие советы
Если вы хотите, чтобы размер файла данных был как можно меньшим, вот несколько советов:
- Запишите данные в двоичный файл (т.е.с использованием FWRITE) вместо текстового файла (т.е.с использованием ФПРИНТФ).
- Если ваши данные содержат все целочисленные значения, преобразуйте их или сохраните как целочисленный тип со знаком или без знака вместо стандартного тип двойной точности MATLAB использует.
- Если ваши данные содержат значения с плавающей запятой, но вам не нужен диапазон или разрешение значения по умолчанию тип двойной точности, конвертируйте его или сохраните как тип одинарной точности.
- Если ваши данные достаточно разрежены (т.нулей в вашей матрице намного больше, чем ненулевых), тогда вы можете использовать НАХОДИТЬ чтобы получить индексы строк и столбцов ненулевых значений, а затем просто сохраните их в свой файл.
Вот несколько примеров для иллюстрации:
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
Файлы, созданные выше, будут сильно отличаться по размеру.Файл 'data_double.dat'
будет около 131 073 КБ, 'data_uint8.dat'
будет около 16 385 КБ, а 'data_sparse.dat'
будет меньше 2 КБ.
Обратите внимание, что я также записал в файлы размеры данных\векторов, чтобы данные можно было прочитать обратно (используя ФРЕД) и изменена должным образом.Обратите также внимание, что если бы я не предоставил 'double'
или 'uint8'
аргумент для FWRITE, MATLAB был бы достаточно умен, чтобы понять, что ему не нужно использовать двойную точность по умолчанию, и для записи значений данных будет использоваться только 8 бит (поскольку все они равны 0 и 1).
Как созданы данные? Как вам нужно получить доступ к данным?
Если я правильно рассчитаю, переменная менее 200 МБ, если она все двойной. Таким образом, вы можете легко сохранить и загрузить его как один файл .mat, если вам нужно получить доступ к нему из MatLab.
%# 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')