Самый быстрый способ импортировать файлы CSV в MATLAB

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

Данные представлены в следующем формате:

Item1,val1,val2,val3
Item2,val4,val5,val6,val7
Item3,val8,val9

где заголовки находятся в самом левом столбце, а значения данных занимают оставшуюся часть строки. Одна из основных трудностей заключается в том, что массивы значений данных могут иметь разную длину для каждого элемента теста. Я бы сохранил его как структуру, но мне нужно иметь возможность редактировать его вне среды MATLAB, поскольку иногда мне приходится удалять строки неверных данных на компьютере, на котором не установлен MATLAB. Итак, первая часть моего вопроса: следует ли сохранять данные в другом формате?

Вторая часть вопроса: я пробовал importdata , csvread и dlmread, но я не уверен, что лучше, или есть ли лучшее решение . Прямо сейчас я использую свой собственный скрипт с циклом и fgetl, что ужасно медленно для больших файлов. Какие-либо предложения?

function [data,headers]=csvreader(filename); %V1_1
 fid=fopen(filename,'r');
 data={};
 headers={};
 count=1;
 while 1
      textline=fgetl(fid);
      if ~ischar(textline),   break,   end
      nextchar=textline(1);
      idx=1;
      while nextchar~=','
        headers{count}(idx)=textline(1);
        idx=idx+1;
        textline(1)=[];
        nextchar=textline(1);
      end
      textline(1)=[];
      data{count}=str2num(textline);
      count=count+1;
 end
 fclose(fid);

(Я знаю, что это, вероятно, ужасно написанный код - я инженер, а не программист, пожалуйста, не кричите на меня - однако любые предложения по улучшению будут приветствоваться.)


person Doresoom    schedule 11.01.2010    source источник


Ответы (4)


Вероятно, было бы легче читать данные, если бы вы могли дополнить файл NaN значения, когда ваш первый скрипт создает его:

Item1,1,2,3,NaN
Item2,4,5,6,7
Item3,8,9,NaN,NaN

или вы можете даже просто напечатать пустые поля:

Item1,1,2,3,
Item2,4,5,6,7
Item3,8,9,,

Конечно, для правильного заполнения вам нужно заранее знать максимальное количество значений для всех элементов. В любом из указанных выше форматов вы можете использовать одну из стандартных функций чтения файлов, например TEXTSCAN например:

>> fid = fopen('uneven_data.txt','rt');
>> C = textscan(fid,'%s %f %f %f %f','Delimiter',',','CollectOutput',1);
>> fclose(fid);
>> C{1}

ans = 

    'Item1'
    'Item2'
    'Item3'

>> C{2}

ans =

     1     2     3   NaN  %# TEXTSCAN sets empty fields to NaN anyway
     4     5     6     7
     8     9   NaN   NaN
person gnovice    schedule 11.01.2010

Вместо разбора строки textline по одному символу за раз. Например, вы можете использовать strtok, чтобы разбить строку.

stringParts = {};
tline = fgetl(fid);
if ~ischar(tline), break, end
i=1;
while 1
    [stringParts{i},r]=strtok(tline,',');
    tline=r;
    i=i+1;
    if isempty(r), break; end
end

% store the header
headers{count} = stringParts{1};

% convert the data into numbers
for j=2:length(stringParts)
    data{count}(j-1) = str2double(stringParts{j});
end
count=count+1;
person Azim J    schedule 11.01.2010

У меня была такая же проблема с чтением данных csv в Matlab, и я был удивлен тем, как мало поддержки для этого, но потом я только что нашел инструмент импорта данных. Я в r2015b.

В верхней панели на вкладке «Главная» нажмите «Импорт данных» и выберите файл, который хотите прочитать. Появится окно приложения:

Снимок экрана инструмента импорта данных

В разделе «Импортировать выбор» у вас есть возможность «сгенерировать функцию», которая дает вам довольно много вариантов настройки, в том числе то, как заполнять пустые ячейки и какой вы хотите, чтобы структура выходных данных была. Кроме того, он написан MathWorks, поэтому он, вероятно, использует самый быстрый доступный метод для чтения файлов csv. Это было почти мгновенно в моем файле.

person Imperssonator    schedule 15.08.2016

В1) Если вы знаете максимальное количество столбцов, вы можете заполнить пустые записи NaN. Кроме того, если все значения числовые, вам действительно нужен столбец «Элемент №»? Если да, вы можете использовать только «#», чтобы все данные были числовыми.

Q2) Самый быстрый способ прочитать число. данные из файла без mex-файлов — csvread. Я стараюсь не использовать строки в CSV-файлах, но если нужно, использую свою функцию csv2cell:

http://www.mathworks.com/matlabcentral/fileexchange/20135-csv2cell

person Serg    schedule 11.01.2010
comment
Столбец Item# на самом деле представляет собой текстовые метки, так что да, мне это нужно. Я, наверное, должен был уточнить это. - person Doresoom; 11.01.2010