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

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

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

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

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

вторая часть вопроса: Я пытался данныхимпорта, 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);

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

вместо разбора строки объект 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;

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

на верхней панели вкладки "Главная" нажмите "Импортировать данные" и выберите файл, который вы хотите прочитать. Окно приложения появится следующим образом:

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

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


Q1) если вы знаете максимальное количество столбцов, вы можете заполнить пустые записи NaN Кроме того, если все значения являются числовыми, вам действительно нужен столбец "Item#"? Если да, вы можете использовать только "#", поэтому все данные числовые.

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

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