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

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

採用された回答

Atsushi Ueno
Atsushi Ueno 2021 年 7 月 18 日
編集済み: Atsushi Ueno 2021 年 7 月 18 日
① 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 件のコメント
Takafumi Amano
Takafumi Amano 2021 年 7 月 18 日
回答ありがとうございました.
連長圧縮というのは初めて知り,たいへん勉強になりました.
ありがとうございました.

サインインしてコメントする。

その他の回答 (1 件)

Hernia Baby
Hernia Baby 2021 年 7 月 18 日
編集済み: Hernia Baby 2021 年 7 月 18 日
まずは下準備
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 件のコメント
Takafumi Amano
Takafumi Amano 2021 年 7 月 18 日
回答ありがとうございました.
diff関数をすっかり忘れていました.
ありがとうございました.

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeCalendar についてさらに検索

製品


リリース

R2020b

Community Treasure Hunt

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

Start Hunting!