初心者によるMATLABメモ

3次元形状やってんのになぜかMATLABを使わされることになった人のメモ。

<<Optimization Toolboxのドキュメント | ホーム | 積分>>

 

検索エンジンから来た方は読みたい記事が表示されていない可能性があります。
その場合、左メニューのフォームでブログ内を検索すると見たい記事を見れると思います。
もしくは、カテゴリー名をクリックしていただくと各カテゴリーの記事のリストが見れます。

[スポンサー広告] スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
このエントリに付けられたタグ|

[ファイル操作] CSV形式のデータの読み書き

ありがちなcsvファイル(カンマ区切り)の読み込みと書き出しです。
ただ,ここで紹介する関数csvwriteとcsvreadはその関数名から期待されるような動きはテンでしてくれませんのであしからず…
まず『,"1,2,2",』みたいな正しいフォーマットのcsvを読みこまないのはまだ許せますが,文字列も読み込みません.
数字だけ…
まぁそれでも利用価値はあるかなぁと思うので書いておきます.
まぁ面倒でない人は,,csvread()はdlmread(filename, ',', r, c)へのショートカットなのでdlmreadを使った方がよいです。
それに他の区切り文字の場合も気にせず使えますから。
とか言うと見も蓋もないですが、ここでは一応MATLAB様が用意してくださっているcsvwriteとcsvreadを使ってみます。
一応ただ使うだけならこっちの方が便利ではあるので。

基本的にはこれです↓
書き込み = csvwrite('filename',M)もしくはdlmwrite('filename',M,',')
読み込み = M = csvread('filename') もしくは dlmread('filename',',')
部分読み込み = M = csvread('filename',row,col,range)もしくはdlmread('filename',',',range)
※rangeは省略可。指定する場合[始点行,始点列,終点行,終点列]
※ここでのrow,col,rangeにおいてはなぜかMATLAB標準の1から始まるインデックスではなく1列目が0で表されるので注意!!

実際に下記のような乱数の5x5行列Aを保存して読み込んでみます。
>> A=rand(5)
A =
    0.9501    0.7621    0.6154    0.4057    0.0579
    0.2311    0.4565    0.7919    0.9355    0.3529
    0.6068    0.0185    0.9218    0.9169    0.8132
    0.4860    0.8214    0.7382    0.4103    0.0099
    0.8913    0.4447    0.1763    0.8936    0.1389

書き込みは,こんな感じです↓
一応,書き込みの方は文字列もいけます。
>> csvwrite('Amatrix.csv',A);
>> csvwrite('abcd.csv',['a','b';'c','d']);

次に読み込み。
多分こっちの方が利用する回数は多いかと思います。
まず,ただ行列Aを読み込んでの復元。
>> clear all;
>> A = csvread('Amatrix.csv')
A =
    0.9501    0.7621    0.6154    0.4057    0.0579
    0.2311    0.4565    0.7919    0.9355    0.3529
    0.6068    0.0185    0.9218    0.9169    0.8132
    0.4860    0.8214    0.7382    0.4103    0.0099
    0.8913    0.4447    0.1763    0.8937    0.1389

続いて,行列Aの一部分を読み込んでみます。
ここで注意したいのが通常MATLABでは配列,行列において1からインデックスが始まりますが,1列目,1行目が0で表されるところ。
なんでこんな仕様になっているのかはイマイチ謎ですが,
察するにcsvread()というかdlmread()の仕様が,
ファイルから1行読み込んだ後,
setdiff(sprintf(' bt'),デリミタ文字)として
1行をデリミタ文字でスプリットして配列化しているせいかなぁとか思います。
この場合だと1列しかデータがない場合0ですからね。
で,これに合わせて行の指定の方も0から始まってるということです。
個人的にはどうせなら引数はMATLABに添った形で1づつ引いてくれよと思いますが。

まぁ結局csvファイルの場合ならば何個カンマを読んだ後のデータからを読み込むか?という方法でrowとcolを指定することになってます。
下記の例の場合,行列Aの3行目以降2列目以降のみを読み込みます。
>> A2 = csvread('Amatrix.csv',2,1)
A2 =
    0.0185    0.9218    0.9169    0.8132
    0.8214    0.7382    0.4103    0.0099
    0.4447    0.1763    0.8937    0.1389

この作業は一度全部を読み込んでA(row+1:length(A(:,1)),col+1:length(A(1,:)))を取り出すのと同じです。
>> isequal(A2,A(3:length(A(:,1)),2:length(A(1,:))))
ans =
     1

続いて,範囲指定しての行列Aの部分の取り出し。
>> A3 = csvread('Amatrix.csv',2,0,[2,0,3,2])
A3 =
    0.6068    0.0185    0.9218
    0.4860    0.8214    0.7382

このとき,始点の位置を間違えてみたりすると切り取り線の外側の範囲にある要素は0として返ってきます。
>> A3 = csvread('Amatrix.csv',1,1,[2,0,3,2])
警告: R and C should match RANGE(1:2).  Use DLMREAD(FILE,DELIMITER,RANGE) instead.
> In dlmread at 110
  In csvread at 47

A3 =
         0         0         0         0
         0    0.0185    0.9218    0.9169
         0    0.8214    0.7382    0.4103

最後に時間を計ってみましたが,csvreadの部分取出しと全体読み出し後に部分を取り出すのはあまり時間的には差異はないようです。
というかここまで書いておいてなんですが,csvread()はdlmread(filename, ',', r, c,)への単なるショートカットなので使わないのが一番アツイような気がします。
まぁそこまで遅くならないのでどうでもいいかもですが,他の区切り文字の場合も使えるという意味ではdlmread()の方を覚えておくのがよいかなぁとか思います。
>> csvwrite('Bmatrix.csv',rand(1000,10));
>> tic;for ind=1:100 B = csvread('Bmatrix.csv',20,1);end;toc;
経過時間は2.918437秒です
>> tic;for ind=1:100 B2 = csvread('Bmatrix.csv');B2=B2(21:length(B2(:,1)),2:length(B2(1,:)));end;toc;
経過時間は2.866840秒です
>> tic;for ind=1:100 B3 = csvread('Bmatrix.csv');aa=size(B2);B2=B2(21:aa(1),2:aa(2));end;toc;
経過時間は2.867893秒です
>> tic;for ind=1:100 B4 = csvread('Bmatrix.csv');B4=B4(21:1000,2:10);end;toc;
経過時間は2.891784秒です
>> tic;for ind=1:100 B5 = dlmread('Bmatrix.csv',',',20,1);end;toc;
経過時間は2.810123秒です


csvwrite (MATLAB Function Reference)
csvread (MATLAB Function Reference)
dlmread (MATLAB Function Reference)
dlmwrite (MATLAB Function Reference)
スポンサーサイト
このエントリに付けられたタグ|MATLABcsvファイル操作カンマ区切り

コメント

私のミスかもしれませんがcsvwriteは8桁?で書きだす際に勝手に四捨五入するようです.
例えば数字でナンバリングしてある場合などは致命的なこともあるかと.
  1. 2010/07/15(木) 09:48:39 |
  2. URL |
  3. #-
  4. [ 編集]

csvwriteだと有効桁数を指定できないので、固定になってしまうかと思います。
(私の環境2007bでは整数5ケタで丸められてしまいました。)

csvwriteは文中にもあるとおりdlmwriteへのショートカットなのですが、
もしより多くの有効桁数が必要であれば、
dlmwriteを使って、たとえば下記のようにすれば16桁になるはずです。
dlmwrite('aaa.csv',M,'delimiter',',','precision',16)
  1. 2010/07/16(金) 00:51:14 |
  2. URL |
  3. 管理人 #O41bhH7A
  4. [ 編集]

やはり基本はdlmwriteがべんりですね.
いつも参考にさせていただいてます.ありがとうございます.
  1. 2010/07/20(火) 15:45:13 |
  2. URL |
  3. #-
  4. [ 編集]

コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバックURLはこちら
http://sach1o.blog80.fc2.com/tb.php/15-9c7b198c
この記事にトラックバックする(FC2ブログユーザー)

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。