Загрузка конкретной переменной с индексацией из MAT-файла - PullRequest
2 голосов
/ 17 марта 2011

У меня есть фреймворк на машине с большим количеством оперативной памяти, который создает MAT-файлы с одной очень большой и специально названной матрицей.Вычисление этой матрицы выполняется только один раз и занимает много времени.Наконец, он сохраняется в файле MAT на диске.

На этапе использования этот файл MAT должен быть загружен.Проблема в том, что мне не нужны все данные - только определенный выбор столбцов из этой матрицы.

Например, у меня есть матричный знак в файле crfh.mat размером [500x250000]Тип двойной.Мне может быть интересно загружать только векторы, использующие «идентификаторы» из этой матрицы:

знак (:, идентификаторы)

Есть ли способ сделать это?Я искал в Интернете, и никто, кажется, не выразил потребность в такой функциональности.Я думаю написать MEX функцию select_mat (), например:

sign_sub = select_mat (mat_file, var_name, ids);

Ответы [ 2 ]

3 голосов
/ 17 марта 2011

Если у вас есть одна действительно большая матрица, в которую вы хотите загружать только части, я бы не сохранил ее в виде файла .MAT. Было бы более эффективно записать матрицу в собственный двоичный файл. Тогда вы можете использовать такие функции, как FSEEK , чтобы переходить к различным индексированным точкам в файле и читать только то, что вам нужно. Например, давайте сначала сохраним образец матрицы меньшего размера в двоичный файл, используя функцию FWRITE :

>> M = magic(5)  %# A sample matrix
M =
    17    24     1     8    15
    23     5     7    14    16
     4     6    13    20    22
    10    12    19    21     3
    11    18    25     2     9

>> fid = fopen('bigmatrix.dat','w');  %# Open the file for writing
>> fwrite(fid,size(M),'uint8','l');   %# Write the matrix size (needed later) as
                                      %#   2 unsigned 8-bit (1-byte) integers
>> fwrite(fid,M,'uint8','l');         %# Write the matrix data as unsigned 8-bit
                                      %#   (1-byte) integers
>> fclose(fid);                       %# Close the file

Теперь мы можем прочитать только третий столбец, используя функции FREAD и FSEEK :

>> colIndex = 3;
>> fid = fopen('bigmatrix.dat','r');    %# Open the file for reading
>> sizeM = fread(fid,2,'uint8','l');    %# Read the first two bytes to get the
                                        %#   size of the matrix in the file
>> fseek(fid,sizeM(1)*(colIndex-1),0);  %# Seek forward by an amount of two
                                        %#   columns worth of bytes
>> colData = fread(fid,sizeM(1),'uint8','l');  %# Read column 3 data
>> fclose(fid);                         %# Close the file
>> disp(colData)                        %# Confirm that the right column was read
     1
     7
    13
    19
    25

Это всего лишь простой пример. Возможно, вы захотите записать в файл другую информацию (например, информация заголовка ), такую ​​как размер байта или тип данных каждого значения в матрице. Это может показаться чем-то большим, чем просто выгрузка файлов в файл .MAT, и это так, но если эффективность операций файлового ввода-вывода представляет собой большую проблему, в этом случае лучше создать собственный формат файла для обработки данных. *

2 голосов
/ 17 марта 2011

Вы можете загрузить определенные переменные из файла .mat, который имеет несколько переменных.Тем не менее, я не думаю, что вы можете загрузить только набор произвольных индексов из переменной в MATLAB.

Тем не менее, если ваша проблема относится к типу, в котором вам нужен доступ только к определенным строкам / столбцам, то я могу найти обходной путь для вас.

Вы можете создать struct из матрицы, с каждым столбцом в качестве отдельного поля, а затем сохранить файл .mat с параметром -struct, чтобы каждое поле сохранялось как отдельная переменная.Таким образом, вы можете извлечь тот, который вам нужен.

dummy=randn(100,200);%# this is a test matrix
[dim1,dim2]=size(dummy);

dummyCell=mat2cell(dummy,dim1,ones(dim2,1));%# create a cell from the matrix
fieldNames=strcat(repmat({'col'},1,dim2),cellfun(@num2str,mat2cell(1:dim2,1,ones(dim2,1)),'UniformOutput',false));%# generate fieldnames for the struct

dummyStruct=cell2struct(dummyCell,fieldNames,2);%# create the struct
save('myDummyFile','-struct','dummyStruct')

Я не знаю, как напрямую преобразовать матрицу в структуру.Таким образом, вы сначала разбиваете каждый столбец на ячейки (порядок упорядочен потому, что вы указали, что вам нужно получить доступ к столбцам. Если вам нужны строки, вам придется все поменять).Это в клетке dummyCell.Теперь, чтобы сохранить в структуре, нам нужно сгенерировать имена полей.Это в строковой ячейке fieldNames.Он генерирует имена полей в форме col1, col2 и т. Д. ... Вы можете назвать его чем-то значимым, если хотите.Затем мы конвертируем cell в struct, присваивая каждой ячейке соответствующее имя поля.Наконец, файл mat сохраняется с опцией -struct, которая указывает MATLAB сохранять каждое поле как отдельную переменную.Все это должно быть сделано, когда ваша программа сохраняет файл гигантского мата.Теперь, если вам нужен доступ, скажем, col52, все, что вам нужно сделать, это load('myDummyFile','col52').Вы также можете загрузить более одного, если вам нужно.

Помните, это хорошо работает, если у вас есть порядок в ваших требованиях к индексированию (т. Е. Каждая строка / каждый столбец), если вам нужен доступ к произвольным индексам в матрице, тогда это не будет работать.При создании ячеек / структур и их сохранении могут быть некоторые накладные расходы.Но это окупится, если вы собираетесь экономить только один раз, но часто заходите.

Если ваша матрица огромна (500х250000 не так уж велика по сегодняшним стандартам), вам придется следить за проблемами памяти с этим подходом, потому что мы дублируем всю матрицу в ячейку иструктура.Я написал это шаг за шагом, чтобы было понятнее, но вы можете уменьшить дублирование, создав ячейку из dummy и присвоив ее себе и аналогично структуре.Однако это только уменьшает количество копий на 1, поскольку Matlab все еще должен скопировать переменную в память, чтобы назначить ее себе после манипуляции.

...