Translate

【if文】pytnonで二値化したデータの作り方。二値化と微分を組み合わせることでタイミング同定とかに非常に便利【np.diff】

データをいろいろと扱っていると、データの特定のイベントを切り出したりとか、タイミング同定をしたくなる時が多くなってきます。


そこで役に立つのは、データを二値化したうえで、そのデータを微分することです。

これにピーク値同定を組み合わせることで、割と簡単にタイミング同定でき、かつデータをきれいに切り出すことが可能になります。


今回はそんな感じで、データの二値化と微分、ピーク値同定までの処理までをやってみましょう。甘味自身もこのあたりは毎回調べながらやっているから、覚え書きとしてもちょうどいいかもしれません(笑)。


まずはサンプル用のデータを用意。



例のごとくExcelでサンプル用のデータを用意してみます。基本的には、今回は二値化から微分・ピーク同定の所までのプロセスがわかればよいので、データ自体は意味のない数字の羅列とします。

この部分に関しては最終的に各々でやりたいデータに置き換わるでしょう。

今回のデータは、1から10の値のデータの羅列としましょう。

#必要なパッケージのインポート
import numpy as np
import matplotlib.pyplot as plt
testdata = np.loadtxt('testdata.csv',delimiter =',')

plt.plot(testdata)



グラフにするとこんな感じ。


適当な数字の配列なので、このプロット自体に意味はありません。
では今回の課題のデータの二値化として、このデータを2.5を閾値にして二値化してみましょう。


二値化はfor文とif文の組み合わせでやるのが良さそう

では実際に二値化の処理をやってみましょう。二値化の処理で直感的にわかりやすいのは、for文とif文を組み合わせた構成だと思います。


#必要なパッケージのインポート
import numpy as np
import matplotlib.pyplot as plt
testdata = np.loadtxt('testdata.csv',delimiter =',')

plt.plot(testdata)
testdata2 = np.zeros([len(testdata),1])
#二値化用の空の配列を作る。

for i in range(len(testdata)):
    #テストデータの長さ分のループ処理をする
    if testdata[i]>2.5:
        #もしもテストデータのi行目が2.5より大きかったら
       testdata2[i]=1
       #testdata2のi行目に1を代入する
    else:
       testdata2[i]=0
        #それ以外の場合は0を代入
        
plt.plot(testdata2)


グラフ描画してみるとこんな感じになります。しっかりと0と1の配列になっているのがわかります。



微分はnumpyのnp.diff()を使う

この二値化された配列を使って今度は微分をしてみましょう。そうすると特徴的なグラフになります。

コードはこんな感じになります。



#必要なパッケージのインポート
d_testdata2 = np.diff(testdata2,axis=0)
d_testdata2 = np.vstack([0,d_testdata2])
plt.plot(d_testdata2)




緑色のグラフが、微分したグラフになります。二値化したデータを微分するときれいにピークが立ち上がるのがわかります。これをscipyのピーク値同定のモジュールを使うことでうまくタイミング同定することができます。

タイミング同定はscipyのsignal.argrelmax()もしくはargrelmin()を使う。

では先ほどの微分データを使ってタイミング同定をしてみましょう。コードはこんな感じです。それぞれのコードは一行で簡単ですね。


#必要なパッケージのインポート
from scipy import signal

t1 = signal.argrelmax(d_testdata2)[0]
t2 = signal.argrelmin(d_testdata2)[0]
lendata = np.ones(len(t1))

plt.scatter(t1,lendata,color = 'red')
plt.scatter(t2,-lendata,color = 'red')


グラフ描画するとこんな感じです。

こんな感じでタイミングがきれいに同定することができています。このt1、t2の配列に含まれたデータをデータの区切りに使ってやれば、自分の切り出したいデータを分けることができます。