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は、統計処理や機械学習、ディープラーニングといった数値計算分野を中心に幅広い用途で利用されているプログラミング言語です。他のプログラミング言語と比較して「コードが短くて読みやすい、書きやすい」「ライブラリが豊...

コメント
お世話になります。
「【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に修正してみてください.