PythonモジュールPandasでパルス信号の立ち上がり、立ち下がりを計算する方法についてソースコード付きでまとめました。
【Pandas】時間信号データの実効値を計算
パルス信号データ(CSV)を読み込んで、波形の時定数、立上り時間、立下り時間、ON(HIGH)の時間を計算します。
種別 | 概要 |
---|---|
立ち上がり時間 | 時間信号が10%から90%に上がるまでの時間。 |
立ち下がり時間 | 時間信号が90%から10%に下がるまでの時間。 |
時定数 | 時間信号が10%から63.2%に上がるまでの時間。 |
RMS | 二乗平均平方根(Root Mean Square)。二乗した値の平均を求めその平方根を計算する。 【信号処理】実効値の計算式・計算例(Excel、Pythonなど) |
– | 読み込んだデータ |
---|---|
CSV | current.csv |
current.csv
time,current -6,0 -5.8,1 -5.6,0 -5.4,0 ︙ 0,0 0.2,1 0.4,2 ︙ 2.4,13 2.6,12 2.8,16 ︙
サンプルコード
# -*- coding: utf-8 -*- import os import pandas as pd import matplotlib import matplotlib.pyplot as plt import numpy as np import math class Pulse(): # 波形の各種時間(立上り、下がり、ON)を計算 def calc_time(self, ts, ys, Ymax=None, Ymin=None, upper_threshold=0.9, lower_threshold=0.1, Tr_start_min=None, Ton_min=None): dst = {} # 最小時間が指定されていなければ、最も小さい時間をセット if Tr_start_min == None: Tr_start_min = ts.min() # 最小時間が指定されていなければ、最も小さい時間をセット if Ton_min == None: Ton_min = 0 if Ymax == None: Ymax = ys.max() if Ymin == None: Ymin = ys.min() dst["Ymax"] = Ymax dst["Ymin"] = Ymin dst["Yamp"] = Yamp = Ymax - Ymin dst["upper"] = upper_threshold dst["lower"] = lower_threshold # 立上り開始時間(信号がしきい値と最小値を超えた直後の時間)を取得 Trs_start = ts[ys > Yamp * lower_threshold] dst["tr_start"] = Tr_start = Trs_start[Trs_start > Tr_start_min].min() # 立上り終了時間を取得 Trs_end = ts[ys > Yamp * upper_threshold] dst["tr_end"] = Tr_end = Trs_end[Trs_end > Tr_start].min() # 立上り時間を計算 dst["tr"] = Tr = Tr_end - Tr_start # 立下り開始時間を取得( > 立上り終了時間 + ON最小時間) try: Tfs_start = ts[ys < Yamp * upper_threshold] dst["tf_start"] = Tf_start = Tfs_start[Tfs_start > Tr_end + Ton_min].min() except: dst["tf_start"] = Tf_start = ts[-1] # ONの時間を計算(立上り終了時間~立下り開始時間) dst["ton"] = Ton = Tf_start - Tr_end # 立下り終了時間を取得 try: Tfs_end = ts[ys < Yamp * 0.1] dst["tf_end"] = Tf_end = Tfs_end[Tfs_end > Tf_start].min() except: dst["tf_end"] = Tf_end = ts[-1] # 立下り時間を計算 dst["tf"] = Tf = Tf_end - Tf_start # 時定数を計算 taus = ts[ys >= Yamp * 0.632] dst["tau"] = tau = taus[taus > Tr_start_min].min() - Tr_start self.pulse_times = dst return dst # 波形の各種時間(立上り、下がり、ON)を計算 def show_time(self): dst = {} tr_start = self.pulse_times["tr_start"] tr_end = self.pulse_times["tr_end"] tr = self.pulse_times["tr"] ton = self.pulse_times["ton"] tf_start = self.pulse_times["tf_start"] tf_end = self.pulse_times["tf_end"] tf = self.pulse_times["tf"] tau = self.pulse_times["tau"] Ymax = self.pulse_times["Ymax"] Ymin = self.pulse_times["Ymin"] Yamp = self.pulse_times["Yamp"] print("Tr start:", tr_start) print("Tr end:", tr_end) print("Tr:", tr) print("Ton:", ton) print("Tf start:", tf_start) print("Tr end:", tf_end) print("Tf:", tf) print("Tau:", tau) def save_graph(self, x, y, xlabel, ylabel, save_path, label_name="Y"): tr_start = self.pulse_times["tr_start"] tr_end = self.pulse_times["tr_end"] tr = self.pulse_times["tr"] ton = self.pulse_times["ton"] tf_start = self.pulse_times["tf_start"] tf_end = self.pulse_times["tf_end"] tf = self.pulse_times["tf"] tau = self.pulse_times["tau"] Ymax = self.pulse_times["Ymax"] Ymin = self.pulse_times["Ymin"] Yamp = self.pulse_times["Yamp"] upper_threshold = self.pulse_times["upper"] lower_threshold = self.pulse_times["lower"] # 保存先のディレクトリパスが存在しなければ作成 dir_path = os.path.dirname(save_path) if not os.path.exists(dir_path): os.mkdir(dir_path) # グラフ化 ax = plt.axes() plt.rcParams['font.family'] = 'Times New Roman' # 全体のフォント plt.rcParams['axes.linewidth'] = 1.0 # 軸の太さ # 電流値をプロット plt.plot(x, y, lw=1, c="r", alpha=0.7, ms=2, label=label_name) # 立上り・下りの開始、終了時間、時定数に垂線をプロット plt.vlines(tr_start, min(y), max(y), ls='--', color="b", lw=1, label="Tr start") plt.vlines(tr_end, min(y), max(y), ls='--', color="g", lw=1, label="Tr end") plt.vlines(tf_start, min(y), max(y), ls='--', lw=1, label="Tf start") plt.vlines(tf_end, min(y), max(y), ls='--', color="m", lw=1, label="Tf end") plt.vlines(tau, min(y), max(y), ls='-', lw=1, label="Tau") # 電流最大値の10%、90%に水平線をプロット plt.hlines(Yamp * 0.9, min(x), max(x), ls='--', color="r", lw=1, label="Amp " + str(upper_threshold*100)+"%") plt.hlines(Yamp * 0.1, min(x), max(x), ls='--', color="y", lw=1, label="Amp " + str(lower_threshold*100)+"%") # グラフの保存 plt.legend(loc="best") # 凡例の表示(2:位置は第二象限) plt.xlabel('Time[msec]', fontsize=12) # x軸ラベル plt.ylabel('Current[A]', fontsize=12) # y軸ラベル plt.grid() # グリッドの表示 plt.legend(loc="best") # 凡例の表示 plt.savefig(save_path) plt.clf() # 実効値の計算 def calc_rms(self, y): return math.sqrt(np.sum(y ** 2) / y.size) def main(): pulse = Pulse() # 読み込むCSVファイルのパス csv_path = "C:/prog/python/auto/current.csv" save_path = "C:/prog/python/auto/" # 空のデータフレームを作成 df = pd.DataFrame({}) # CSVファイルのロードし、データフレームへ格納 df = pd.read_csv(csv_path, encoding="UTF-8", skiprows=0) # 電流値の列データを取り出し Its = df.loc[:, "current"] # 経過時間の列データを取り出し ts = df.loc[:, "time"] # 各種時間を計算(上限90%、下限10%) pulse.calc_time(ts, Its, Ymin=0, Ton_min=50) times = pulse.show_time() pulse.save_graph( ts, Its, xlabel="Time[msec]", ylabel="Current[A]", save_path=save_path+"a.png", label_name="I(t)") """ Tr start: 8.4 Tr end: 328.2 Tr: 319.8 Ton: 278.8 Tf start: 607.0 Tr end: 620.8 Tf: 13.799999999999955 Tau: 114.39999999999999 RMS: 249.061976770524 """ print("RMS:", pulse.calc_rms(Its)) if __name__ == "__main__": main()
【Python】Pandasで信号処理入門
PythonモジュールPandasで信号処理する方法についてまとめました。
【Pandas入門】使い方とサンプル集
Pythonモジュール「Pandas」でデータ分析する方法についてサンプルコード付きで入門者向けに解説します。
【Python超入門】使い方とサンプル集
Pythonの使い方について、基礎文法から応用例まで入門者向けに解説します。
コメント
お世話になります。
「【Python/Pandas】パルス信号の時定数、立ち上がり、立ち下がりを計算」のコードを実行したのですが、WIN10ではうまくいったのですが、ラズパイ(ターミナルから実施)で実施するとうまくいきませんでした。データのCSVは同じです。
Win10とラズパイ(Linux)の違いだと、思いますが、もし心当たりがあれば教えてください。
↓
Traceback (most recent call last):
File “Delay_1.py”, line 196, in
main()
File “Delay_1.py”, line 180, in main
ts, Its, xlabel=”Time[msec]”, ylabel=”Current[A]”, save_path=save_path+”a.png”, label_name=”I(t)”)
File “Delay_1.py”, line 129, in save_graph
color=”b”, lw=1, label=”Tr start”)
File “/usr/lib/python3/dist-packages/matplotlib/pyplot.py”, line 3036, in vlines
**kwargs)
File “/usr/lib/python3/dist-packages/matplotlib/__init__.py”, line 1812, in inner
return func(ax, *args, **kwargs)
File “/usr/lib/python3/dist-packages/matplotlib/axes/_axes.py”, line 1143, in vlines
lines.update(kwargs)
File “/usr/lib/python3/dist-packages/matplotlib/artist.py”, line 916, in update
ret = [_update_property(self, k, v) for k, v in props.items()]
File “/usr/lib/python3/dist-packages/matplotlib/artist.py”, line 916, in
ret = [_update_property(self, k, v) for k, v in props.items()]
File “/usr/lib/python3/dist-packages/matplotlib/artist.py”, line 912, in _update_property
raise AttributeError(‘Unknown property %s’ % k)
AttributeError: Unknown property ls
コメントありがとうございます. ls引数がないと怒られているようですのでlsをlinestyleに修正してみてください.