本プログラムの概要は下図です。X,Yデータにおいて、Yデータを昇順(小→大)に順番に指定したY値を越えるかを調べます。もし、指定したYを越えたらその前後の(X, Y)値を取得して対数log補完により傾きを計算します。そして、その傾きを利用して指定したYに交差するXを抽出してファイルへ書き出します。
▼本プログラム実行後は、下図のようなextracted_data.txtファイルを出力します。図例では、Y=2.5e-10と交差するのはX=1.0283718977664713 ということです。
▼本プログラム
汎用性を持たせるために、基本パラメータは一か所へ、変数名に代入する仕様にしています。if __name__ == '__main__': 以下に、読み出すcsvファイル名、X,Yデータつまり列名の指定、データをソート(並び替え)またYデータを掛け算して前処理する値等を指定できます。
import os, sys, glob
import pandas as pd
import numpy as np
import math
class Extract_target:
def __init__(self, my_path, my_startrow):
self.df = pd.read_csv(my_path, skiprows=my_startrow, encoding="shift-jis")
self.fname = my_path[:-4]
print(self.df)
def calc_X(self, my_columns, my_scale, my_sort, my_target):
df2 = self.df[[my_columns[0], my_columns[1]]]
df3 = df2.drop(0)
df3_s = df3.sort_index(ascending=False)
add_column_name = my_columns[1] + " * " + str(my_scale)
df3_s[add_column_name] = df3_s.apply(lambda x: f"{float(x[my_columns[1]]) * my_scale}", axis=1)
print(df3_s)
df3_s.to_csv(str(self.fname) + "_extract.csv")
my_Ylist = df3_s[add_column_name].values.T
my_Xlist = df3_s[my_columns[0]].values.T
for i in range(len(my_Ylist)):
if i==0:
pass
else:
y2 = float(my_Ylist[i])
x2 = float(my_Xlist[i])
y1 = float(my_Ylist[i-1])
x1 = float(my_Xlist[i-1])
if ( y2 > my_target ) and ( y1 <= my_target ):
slope = (math.log10(y2) - math.log(y1))/(x2 - x1)
x = (math.log10(my_target) - math.log10(y1))/slope + x1
print("i -> " + str(i))
print("x1, y1 -> " + str(x1) + " " + str(y1))
print("x2, y2 -> " + str(x2) + " " + str(y2))
print("x -> " + str(x))
return x
if y1 > my_target:
return "NaN"
def write_target(my_outname, my_value):
tmp_list = [my_outname, str(my_value), '
']
with open("extracted_data.txt", "a") as f:
f.writelines(tmp_list)
if __name__ == '__main__':
my_path = "raw_data.csv"
my_startrow = 0
my_columns = ('C', 'D')
my_scale = 1/2
my_sort = True
my_target = 2.5e-10
my_outname = 'X@' + str(my_target) + "="
DF = Extract_target(my_path, my_startrow)
X = DF.calc_X(my_columns, my_scale, my_sort, my_target)
write_target(my_outname, X)
以下は、もう少し詳しい補足です。
▼扱うデータの例(生データ)
下表のようなデータを「csvファイル」として準備します。(X, Y)は列名(A, B)、(C, D)などとしてプログラム内で指定して処理するため、何列あっても良いです。本記事のポイントは、BやDのような数値が桁で変化するような、対数(log)でデータ処理したい場合に関する。
A |
B |
C |
D |
0 |
1.00E-15 |
11 |
1.00E-05 |
0.5 |
1.00E-14 |
10 |
6.00E-06 |
1 |
1.00E-13 |
9 |
4.00E-06 |
1.5 |
1.00E-12 |
8 |
2.00E-06 |
2 |
1.00E-10 |
7 |
1.00E-06 |
2.5 |
1.00E-09 |
6 |
6.00E-07 |
3 |
1.00E-08 |
5 |
4.00E-07 |
3.5 |
1.00E-07 |
4 |
2.00E-07 |
4 |
2.00E-07 |
3 |
2.00E-08 |
4.5 |
3.00E-07 |
2 |
2.00E-09 |
5 |
5.00E-07 |
1 |
2.00E-10 |
5.5 |
1.00E-06 |
0 |
2.00E-12 |
6 |
2.00E-06 |
-1 |
2.00E-13 |
6.5 |
3.00E-06 |
-2 |
2.00E-14 |
7 |
5.00E-06 |
-3 |
2.00E-15 |
▼実行処理の過程は、下図のようにprint関数で出力している。csvファイルを読み込み、指定した(X, Y)データ(例ではC,D)についてソートして、Yを0.5倍の前処理を行っています。そして、指定したY(例では2.5e-10)前後の(x1,y1)(x2,y2)と、(x, 指定したY)の値が出力された様子です。
以上
<広告>
リンク