私は数日間MATLABを使用していますが、CSVファイルをマトリックスにインポートするのが困難です。
私の問題は、CSVファイルにはほとんど文字列と整数値しか含まれていないため、csvread()
が機能しないことです。 csvread()
は整数値とのみ一致します。
各要素に自由にアクセスできるように、文字列を何らかの2次元配列に格納するにはどうすればよいですか?
これが私のニーズに合ったサンプルCSVです。
04;abc;def;ghj;klm;;;;;
;;;;;Test;text;0xFF;;
;;;;;asdfhsdf;dsafdsag;0x0F0F;;
主なものは、空のセルとセル内のテキストです。ご覧のとおり、構造は異なる場合があります。
CSVファイルに含まれるデータの列数がわかっている場合は、 textscan
like Amro suggests を1回呼び出すだけが最適です溶液。
ただし、ファイル内の列の数のアプリオリがわからない場合は、次の関数でやったように、より一般的なアプローチを使用できます。最初に関数 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' '' ''
結果は、セルごとに1つのフィールドを持つ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
値になります。
あなたが投稿したサンプルを考えると、この単純なコードは仕事をするはずです:
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番目の列を16進数から10進数に変換する場合は、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
詳細 です。
Xlsreadを使用します。csvファイルでも.xlsファイルと同様に機能します。 3つの出力が必要であることを指定します。
[num char raw] = xlsread('your_filename.csv')
数値データのみを含む配列(num)、文字データのみを含む配列(char)、および.csvレイアウトと同じ形式のすべてのデータ型を含む配列(raw)を提供します。
ファイル交換で見つかった「CSVIMPORT」機能を使用しようとしましたか?私は自分で試したことはありませんが、テキストと数字のすべての組み合わせを処理すると主張しています。
http://www.mathworks.com/matlabcentral/fileexchange/23573-csvimport
ファイルの形式によっては、importdataが機能する場合があります。
文字列をセル配列に保存できます。詳細については、「doc cell」と入力してください。
データセット配列を確認することをお勧めします。
データセット配列は、Statistics Toolboxに付属のデータ型です。単一のコンテナに異種データを保存するように特別に設計されています。
Statistics Toolboxのデモページには、データセット配列の機能の一部を示すいくつかのビデオが含まれています。最初のタイトルは「データセット配列の紹介」です。 2番目のタイトルは「結合の概要」です。
入力ファイルにカンマで区切られた固定量の列があり、どの列が文字列であるかがわかっている場合は、関数を使用するのが最善かもしれません
textscan()
文字列の最大文字数まで、または区切り文字(コンマ)が見つかるまで読み取る形式を指定できることに注意してください。
% 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);