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

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

Моя проблема в том, что мой CSV-файл содержит почти только строки и некоторые целочисленные значения, так чтоcsvread() не работаетcsvread() только ладит с целочисленными значениями.

Как я могу хранить свои строки в каком-то двумерном массиве, чтобы иметь свободный доступ к каждому элементу?

Вот образец CSV для моих нужд:

04;abc;def;ghj;klm;;;;;
;;;;;Test;text;0xFF;;
;;;;;asdfhsdf;dsafdsag;0x0F0F;;

Главное - это пустые клетки и тексты внутри клеток. Как видите, структура может отличаться.

 Amro26 янв. 2011 г., 13:37
Вы должны опубликовать пару строк из вашего CSV-файла, чтобы мы поняли, как структурирован файл (являются ли строки цитируемыми' или же", содержат ли они запятые внутри кавычек, также являются целочисленными значениями, есть ли экранированные разделители, такие как"this is \"an example\"" и т.д...)
 poeschlorn27 янв. 2011 г., 11:39
Готово :) Надеюсь, это немного поможет
 zellus20 янв. 2011 г., 15:07
Посмотрите тексты>mathworks.com/help/techdoc/ref/textscan.html

Ответы на вопрос(9)

разделенных запятыми, и вы знаете, в каких столбцах есть строки, лучше всего использовать функцию

textscan()

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

Массив набора данных - это тип данных, который поставляется вместе со Статистическим набором инструментов. Он специально предназначен для хранения гетерогенных данных в одном контейнере.

Демонстрационная страница Statistics Toolbox содержит пару видео, в которых показаны некоторые функции массива наборов данных. Первый из них называется «Введение в массивы наборов данных». Вторая называется «Введение в соединения».

http://www.mathworks.com/products/statistics/demos.html

 Andy Campbell29 окт. 2013 г., 14:52
Смотрите мой ответ ниже, если у вас есть R2013b, это решение будет делать это с таблицей.
 poeschlorn25 янв. 2011 г., 08:22
Спасибо за ваш ответ, примеры выглядят очень полезными, но в моем случае я не установил Statistics Toolbox: /

он работает так же хорошо для файлов .csv, как и для файлов .xls. Укажите, что вы хотите три выхода:

[num char raw] = xlsread('your_filename.csv')

и он даст вам массив, содержащий только числовые данные (num), массив, содержащий только символьные данные (char), и массив, который содержит все типы данных в том же формате, что и формат .csv (raw).

который вы разместили, этот простой код должен сделать работу:

fid = fopen('file.csv','r');
C = textscan(fid, repmat('%s',1,10), 'delimiter',';', 'CollectOutput',true);
C = C{1};
fclose(fid);

Затем вы можете отформатировать столбцы в соответствии с их типом. Например, если в первом столбце целые числа, мы можем отформатировать его так:

C(:,1) = num2cell( str2double(C(:,1)) )

Точно так же, если вы хотите преобразовать 8-й столбец из шестнадцатеричного числа в десятичное, вы можете использовать HEX2DEC:

C(:,8) = cellfun(@hex2dec, strrep(C(:,8),'0x',''), 'UniformOutput',false);

Результирующий массив ячеек выглядит следующим образом:

C = 
    [  4]    'abc'    'def'    'ghj'    'klm'    ''            ''                []    ''    ''
    [NaN]    ''       ''       ''       ''       'Test'        'text'        [ 255]    ''    ''
    [NaN]    ''       ''       ''       ''       'asdfhsdf'    'dsafdsag'    [3855]    ''    ''

В R2013b или позже вы можете использовать таблицу:

>> table = readtable('myfile.txt','Delimiter',';','ReadVariableNames',false)
>> table = 

    Var1    Var2     Var3     Var4     Var5        Var6          Var7         Var8      Var9    Var10
    ____    _____    _____    _____    _____    __________    __________    ________    ____    _____

      4     'abc'    'def'    'ghj'    'klm'    ''            ''            ''          NaN     NaN  
    NaN     ''       ''       ''       ''       'Test'        'text'        '0xFF'      NaN     NaN  
    NaN     ''       ''       ''       ''       'asdfhsdf'    'dsafdsag'    '0x0F0F'    NaN     NaN  

Вотбольше информации.

CSVIMPORT", найденную при обмене файлами? Я не пробовал сам, но он претендует на обработку всех комбинаций текста и чисел.

http://www.mathworks.com/matlabcentral/fileexchange/23573-csvimport

Решение Вопроса

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

Однако, если вы не знаете,априори сколько столбцов в вашем файле, вы можете использовать более общий подход, как я сделал в следующей функции. Я впервые использовал функциюfgetl прочитать каждую строку файла в массив ячеек. Тогда я использовал функциюtextscan проанализировать каждую строку в отдельные строки, используя предопределенный разделитель полей и обрабатывая целочисленные поля как строки (они могут быть преобразованы в числовые значения позже). Вот результирующий код, помещенный в функциюread_mixed_csv:

function lineArray = read_mixed_csv(fileName, delimiter)

  fid = fopen(fileName, 'r');         % Open the file
  lineArray = cell(100, 1);           % Preallocate a cell array (ideally slightly
                                      %   larger than is needed)
  lineIndex = 1;                      % Index of cell to place the next line in
  nextLine = fgetl(fid);              % Read the first line from the file
  while ~isequal(nextLine, -1)        % Loop while not at the end of the file
    lineArray{lineIndex} = nextLine;  % Add the line to the cell array
    lineIndex = lineIndex+1;          % Increment the line index
    nextLine = fgetl(fid);            % Read the next line from the file
  end
  fclose(fid);                        % Close the file

  lineArray = lineArray(1:lineIndex-1);              % Remove empty cells, if needed
  for iLine = 1:lineIndex-1                          % Loop over lines
    lineData = textscan(lineArray{iLine}, '%s', ...  % Read strings
                        'Delimiter', delimiter);
    lineData = lineData{1};                          % Remove cell encapsulation
    if strcmp(lineArray{iLine}(end), delimiter)      % Account for when the line
      lineData{end+1} = '';                          %   ends with a delimiter
    end
    lineArray(iLine, 1:numel(lineData)) = lineData;  % Overwrite line data
  end

end

Запуск этой функции для содержимого файла примера из вопроса дает такой результат:

>> data = read_mixed_csv('myfile.csv', ';')

data = 

  Columns 1 through 7

    '04'    'abc'    'def'    'ghj'    'klm'    ''            ''        
    ''      ''       ''       ''       ''       'Test'        'text'    
    ''      ''       ''       ''       ''       'asdfhsdf'    'dsafdsag'

  Columns 8 through 10

    ''          ''    ''
    '0xFF'      ''    ''
    '0x0F0F'    ''    ''

В результате получается массив ячеек размером 3 на 10 с одним полем на ячейку, где пропущенные поля представлены пустой строкой.'', Теперь вы можете получить доступ к каждой ячейке или комбинации ячеек, чтобы отформатировать их, как вам нравится. Например, если вы хотите изменить поля в первом столбце со строк на целочисленные значения, вы можете использовать функциюstr2double следующее:

>> data(:, 1) = cellfun(@(s) {str2double(s)}, data(:, 1))

data = 

  Columns 1 through 7

    [  4]    'abc'    'def'    'ghj'    'klm'    ''            ''        
    [NaN]    ''       ''       ''       ''       'Test'        'text'    
    [NaN]    ''       ''       ''       ''       'asdfhsdf'    'dsafdsag'

  Columns 8 through 10

    ''          ''    ''
    '0xFF'      ''    ''
    '0x0F0F'    ''    ''

Обратите внимание, что пустые поля приводят кNaN ценности.

 Alex09 февр. 2016 г., 13:57
Хороший. Textscan не любит пустые входы, хотя. Если в отсканированном CSV-файле есть пустые строки, процедура завершается ошибкой. Я бы посоветовал заменитьlineArray = lineArray(1:lineIndex-1); поind = all(cellfun(@isempty,lineArray),2); lineArray = lineArray(~ind);
 Jonas28 авг. 2014 г., 11:07
См. Также решение @ AndyCampbell ниже для более свежих выпусков Matlab:stackoverflow.com/a/19642332/232610
 Minh Tran17 июл. 2017 г., 06:30
Вы также можете использоватьstrsplit() сCollapseDelimiters параметр установлен вfalse токенизировать каждую строку CSV-файла. Matlab по умолчанию сворачивает последовательные разделители. Установите в false, результат будет таким:{'' '' '' '' '' 'Test' 'text' '0xFF' '' ''} для командыstrsplit(';;;;;Test;text;0xFF;;', ';', 'CollapseDelimiters', false)
% Assuming that the dataset is ";"-delimited and each line ends with ";"
fid = fopen('sampledata.csv');
tline = fgetl(fid);
u=sprintf('%c',tline); c=length(u);
id=findstr(u,';'); n=length(id);
data=cell(1,n);
for I=1:n
    if I==1
        data{1,I}=u(1:id(I)-1);
    else
        data{1,I}=u(id(I-1)+1:id(I)-1);
    end
end
ct=1;
while ischar(tline)
    ct=ct+1;
    tline = fgetl(fid);
    u=sprintf('%c',tline);
    id=findstr(u,';');
    if~isempty(id)
        for I=1:n
            if I==1
                data{ct,I}=u(1:id(I)-1);
            else
                data{ct,I}=u(id(I-1)+1:id(I)-1);
            end
        end
    end
end
fclose(fid);

ImportData может работать.

Вы можете хранить строки в массиве ячеек. Напечатайте "ячейку документа" для получения дополнительной информации.

 Marm0t20 янв. 2011 г., 22:52
Массив ячеек - это то, что нужно OP. OP может даже хранить целочисленные данные там.
 poeschlorn21 янв. 2011 г., 08:25
Привет, Уильям, «ячейка», кажется, очень хорошая структура данных для моей проблемы. Единственное, с чем я не лажу - это importdata, потому что он не читает в пустых ячейках (из моего CSV) в начале строки ... Я импортирую только «[1x89 char]».

Ваш ответ на вопрос