Есть несколько концепций, которые вы должны знать о Matlab.
- Строки хранятся как UINT16 (вроде как, я никогда не могу понять это правильно). Важно то, что это означает, что каждому символу требуется 2 байта. Если вы сохранили весь файл в виде длинной строки, это заняло бы 8 ГБ.
- Значения, будь то массивы или скаляры, хранятся с заголовками. Это означает, что для хранения строки (технически символьный массив, строки - строки с двойными кавычками вместо одинарных кавычек - могут отличаться) требуется заголовок, который составляет примерно 104 байта. Это означает, что что-то вроде 'test' требует приблизительно 108 байтов! Если вы можете хранить массив чисел, тогда издержки на 104 байта минимальны. Если у вас есть массив ячеек скаляров, то каждый скаляр занимает 112 байтов (при условии, что скаляр является 8-байтовым двойным). Это может немного сбивать с толку, но, в конце концов, это означает, что если вы не будете внимательно читать CSV-файл, ваши требования к памяти могут взорваться.
Так что вы можете сделать. Таблицы хранят столбцы как массивы, где это возможно. Вы можете попробовать readtable
, хотя я думаю, что базовая реализация может быть неэффективной для памяти.
Для больших файлов Matlab предлагает использовать функцию datastore
. Это решит проблему с памятью, хотя может быть немного медленным.
Другой вариант - прочитать весь файл в память и выполнить собственную обработку. Например, если у вас ничего не экранировано (то есть запятые, которые на самом деле не являются разделителями), вы можете найти все соответствующие разделители, используя:
%Find comma or newline
I = regexp(temp,',|\n')
Вот пример извлечения различных столбцов. Как указано выше, это имеет большие издержки для строк (символьных массивов), но эффективно для чисел.
%Fake data as an example, 3 columns with middle one numeric
temp = sprintf('asdf,1234,temp\nfred,324,chip\ncheese,12,you are always right');
I = regexp(temp,',|\n');
starts = [0 I];
ends = [I length(temp)+1];
n_columns = 3;
%extract column 2
c2 = arrayfun(@(x,y) str2double(temp(x+1:y-1)),starts(2:n_columns:end),ends(2:n_columns:end));
%extract column 1
c1 = arrayfun(@(x,y) temp(x+1:y-1),...
starts(1:n_columns:end),ends(1:n_columns:end),'un',0);
В зависимости от вашего варианта использования это может работать или не работать. Для чтения файла в память вы можете использовать fileread