MATLAB Answers

時系列データから条件​抽出し、カウントや累​積和を出す方法

9 views (last 30 days)
以下のような時系列データから、2列目の前後Indexを比較し、条件によってTrue,False判定し、
その値に応じてカウントアップをさせたいのですが、なにか良い方法はありませんでしょうか?
イメージは以下のようなデータ1,2列のデータがあり、3~5列のようなデータを付与したいです。
① Index前後によって比較する方法(上記2列目のRoomTempデータから、3列目のような列を作成する方法)
For loopやcircshiftなどを使って、配列をずらし、条件比較し算出する方法は浮かぶのですが、なにかもっと良い別の手法があればご教授いただきたく。
② 他の列の条件によってカウントアップする方法(上記3や4列目のデータから、4や5列目のカウントアップや累積和を作成する方法)
他列の条件により、累積和を出す方法でできると思うのですが、条件により累積和をリセットする方法がわかりません。
カウント自体は条件によって異なるので、常にIndex数が同じとは限らないので、ForLoopで特定数で回すこともできません。
上記①②について、何か良い方法が無いかアドバイスいただきたく、よろしくお願いいたします。

Accepted Answer

Atsushi Ueno
Atsushi Ueno on 18 Jul 2021
Edited: Atsushi Ueno on 18 Jul 2021
① Index前後によって比較する方法:データ内容から「局所的ピークを検出」していると判断しました
局所的最大値 - MATLAB findpeaks - MathWorks 日本:3列目のピーク判定にはfindpeaks関数が最も適します。
局所的最大値を検出 - MATLAB islocalmax - MathWorks 日本:3列目のピーク判定にはislocalmax/min関数も適します。
② 他の列の条件によってカウントアップする方法
連長圧縮 - Wikipedia:4列目のカウントアップは連長圧縮の応用です。専用のMATLAB関数は無いと思いますが関連記事は多数あります。工夫してfor文を無くす事も可能ですがトリッキーなので、普通にfor文でリセットするのが無難だと思います。同様の問題がCodyにもあります。Make a run-length companion vector - MATLAB Cody - MATLAB Central (mathworks.com)
累積和 - MATLAB cumsum - MathWorks 日本:5列目の累積和にはcumsum関数が適しています。
Timestamps = repelem(datetime(2021,7,17,0:8,1,3),2)';
Timestamps(2:2:end).Minute = Timestamps(2:2:end).Minute + 30; % 1列目の時刻
RoomTemp = [25.9467 26.0536 26.191 26.3284 26.0325 26.5575 26.6185 26.6287...
26.153 26.6287 26.6385 26.712 26.835 26.315 26.5982 26.7203 26.7814 26.9]'; % 2列目の室温データ
Var5 = islocalmin(RoomTemp) + 0; % 3列目のピーク判定(0加算はLogical→double値変換の為)
Var3 = 0; % 4列目のカウントアップ(ここから)
for k = ~Var5' % ピーク判定の反転値(ピーク時に0⇒カウントリセット)
Var3 = [Var3; k*Var3(end)+1];
end
Var3 = Var3(2:end); % 4列目のカウントアップ(ここまで)最後に先頭に付けた0を除く
Var4 = cumsum(Var5);% 5列目の累積和
myTable = table(Timestamps, RoomTemp, Var5, Var3, Var4)
myTable = 18×5 table
Timestamps RoomTemp Var5 Var3 Var4 ____________________ ________ ____ ____ ____ 17-Jul-2021 00:01:03 25.947 0 1 0 17-Jul-2021 00:31:03 26.054 0 2 0 17-Jul-2021 01:01:03 26.191 0 3 0 17-Jul-2021 01:31:03 26.328 0 4 0 17-Jul-2021 02:01:03 26.032 1 1 1 17-Jul-2021 02:31:03 26.558 0 2 1 17-Jul-2021 03:01:03 26.619 0 3 1 17-Jul-2021 03:31:03 26.629 0 4 1 17-Jul-2021 04:01:03 26.153 1 1 2 17-Jul-2021 04:31:03 26.629 0 2 2 17-Jul-2021 05:01:03 26.639 0 3 2 17-Jul-2021 05:31:03 26.712 0 4 2 17-Jul-2021 06:01:03 26.835 0 5 2 17-Jul-2021 06:31:03 26.315 1 1 3 17-Jul-2021 07:01:03 26.598 0 2 3 17-Jul-2021 07:31:03 26.72 0 3 3
  1 Comment
Takafumi Amano
Takafumi Amano on 18 Jul 2021
回答ありがとうございました.
連長圧縮というのは初めて知り,たいへん勉強になりました.
ありがとうございました.

Sign in to comment.

More Answers (1)

Hernia Baby
Hernia Baby on 18 Jul 2021
Edited: Hernia Baby on 18 Jul 2021
まずは下準備
clc,clear;
TT = readtimetable('Sample.xlsx');
①Index前後によって比較する方法
diff関数を使います
idx = diff(TT.RoomTemp)<0;
idx = [0; idx]; %最初の行は0
TT.Var5 = double(idx);
②他の列の条件によってカウントアップする方法
純粋にwhileとifで条件分けします。
その1:カウントアップ
Var3 = zeros(length(idx),1);
idx1 = idx;
idx1(1) = 1;
cnt = 1;
num = 0;
while cnt <= length(Var3)
if idx1(cnt) == 1;
num = 1;
else
num = num + 1;
end
Var3(cnt) = num;
cnt = cnt +1;
end
TT.Var3 = Var3;
その2:1がきたら1を足す
Var4 = zeros(length(idx),1);
cnt = 1;
num = 0;
while cnt <= length(Var3)
if idx(cnt) == 1
num = num +1;
end
Var4(cnt) = num;
cnt = cnt +1;
end
TT.Var4 = Var4;
確認してみましょう
head(TT)
ans = 8×4 timetable
Timestamps RoomTemp Var5 Var3 Var4 ____________________ ________ ____ ____ ____ 17-Jul-2021 00:01:03 25.947 0 1 0 17-Jul-2021 00:31:03 26.054 0 2 0 17-Jul-2021 01:01:03 26.191 0 3 0 17-Jul-2021 01:31:03 26.328 0 4 0 17-Jul-2021 02:01:03 26.032 1 1 1 17-Jul-2021 02:31:03 26.558 0 2 1 17-Jul-2021 03:01:03 26.619 0 3 1 17-Jul-2021 03:31:03 26.629 0 4 1
  1 Comment
Takafumi Amano
Takafumi Amano on 18 Jul 2021
回答ありがとうございました.
diff関数をすっかり忘れていました.
ありがとうございました.

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!