タイトルの通り、時系列データの解析やデータのまとめに役立つかもしれない小ネタ。
時系列に並んだデータから何らかのイベント(例えば何かの値が所定値を上回ったとか)が発生した回数や、その時の時間を解析してまとめたいという場合があります。
そんな時にMATLABを使うと結構簡単にやりたいことが出来ちゃいますよという例の紹介です。
やりたいことの例
以下のデータ(エクセルファイルに書かれていることを想定)から、速度が20km/hを超えたときの時間(55秒目)をピックアップします。

やりたいことを実現する方法について
今回調べたいのは速度が20km/hを超えたタイミングです。
つまり、5秒前は20km/h未満だけど、今回が20以上ということを満たすというタイミングを判定してやれば良いということになります。
イメージで表すと以下のような感じです。

このイメージをMATLABスクリプトに落としていきます。
スクリプト例
ここからは具体的なスクリプトの例となります。
ファイルの読み込み
まずはファイルをMATLABに取り込みます。
データがエクセルファイルにまとめられているなら、エクセルファイルであればxlsread関数で読み込めばよいでしょう。
最近(2019から?)だとxlsread関数は非推奨らしいですが。。。
[~, ~, raw] = xlsread('data');
xlsread関数は1番目の戻り値には数値のみが、2番目にはテキストデータのみが、3番目の戻り値には全てのデータが格納されます。
今回は一応ヘッダーの文字列と数値を合わせて取り込むため1,2番目のデータは捨てて、3番目の戻り値だけ取得します。
実行すると変数rawに以下のようなデータが取り込まれると思います。

速度データの取得
読み込んだ時系列のデータから速度の値だけをピックアップします。
ヘッダーが”速度”となっている列の数値データ、つまり2列目の2行目以降のデータが欲しいので
speedData = cell2mat(raw(2 : end, 2));
として、変数speedDataに速度のデータを格納します。
なお、エクセルファイルを取り込んだrawはセル配列のデータなのですが、今後の手順で数値同士の比較を行います。
その場合、セル配列より通常の数値配列のほうが何かと都合がよいので今の段階でcell2mat配列でセル配列を数値の配列に変換しておきます。
実行すると以下のように速度のデータを引っこ抜くことができます。

1サイクルずらしたデータを取得
速度データを1サイクル後ろにずらしたデータを作成します。
speedDataPre = [0; speedData(1 : end - 1)];
0秒目の1サイクルずらしたデータというものは存在しないため、とりあえず最初は0を入れておき、それ以降に1サイクルずらしたデータを格納します。
実行すると以下のような1サイクルずれたデータが作成されます。

判定実施
速度データと、1サイクルずれた速度データを使用して20km/hを超えたタイミングを判定します。
「現在の速度データが20以上かつ5秒前の速度データが20以下を満たす」をスクリプトで表記すると以下のようになります。
ret = speedData >= 20 & speedDataPre <= 20;
これを実行すると以下のような結果となります。

インデックス12だけ1となって他は0となっています。
インデックス12とはすなわち55秒目のことなので、期待した判定が行えることが確認できました。
時間の取得
判定結果を使い、20km/hを超えた時間を取得します。
まずは速度データと同じように時間データを取得します。
timeData = cell2mat(raw(2 : end, 1));
ここから判定結果が1となっているインデックスの値を取り出します。
targetTime = timeData(ret);

無事に取りたかった20km/hを超えた時間を取得することができました。
まとめ
今回はMATLABを使用したデータ解析のお役立ちテクニックを紹介しました。
今回の例のような小さいデータであれば別に目視で見ても問題ないですが、これが何十万行もあるようなデータ、それが大量にあるような場合はとても手で見ることはできません。
時系列データを解析する場合、手動で頑張る前にまずはMATLABで簡単に実現できないか検討してみると良いのではないでしょうか?
コメント