'20/03/21更新:アルゴリズム変更とコードを見易く刷新した。
下図のようなcsvファイルで、3列目の列名「Out」に数値が昇順に並んでいる。抽出したい値が例えば2.5の場合、2.5に近い値を抽出することを目的とする。
No |
In |
Out |
abc |
1 |
21 |
1.2 |
a |
2 |
32 |
1.24 |
b |
3 |
42 |
1.41 |
c |
4 |
58 |
1.72 |
d |
5 |
91 |
1.933 |
e |
6 |
99 |
2 |
f |
7 |
115 |
2.22 |
g |
8 |
132 |
2.67 |
h |
9 |
148 |
2.81 |
i |
10 |
165 |
2.91 |
j |
本プログラムの実行結果を下図に示す。2.5に最も近い値は2.22よりも2.67のため、2.67が抽出されている。その時のInの列の値も抽出してファイルに書き出す仕様とした。
一方、例えば、3を指定した場合は下図のようにNaNを返します。上記データの最大値は2.91であり、指定した3を一度も越えなかっただめである。
▼本プログラム
# -*- coding:utf-8 -*-
import os, sys
import pandas as pd
def getTarget(value_list, target_val):
for i in range(len(value_list)):
if float(value_list[i]) > target_val:
deltaA = float(value_list[i]) - target_val
deltaB = target_val - float(value_list[i-1])
if deltaA <= deltaB:
return value_list[i]
else:
return value_list[i-1]
if float(value_list[i-1]) < target_val:
return False
def main():
df = pd.read_csv(input_path)
value_np = df[target_column].values.T
print (value_np, type(value_np))
got_value = getTarget(value_np, target_val)
print('got_value', got_value)
if got_value:
row_df = df[df[target_column] == got_value]
data1 = str(row_df[extract_column].values[0])
data2 = str(got_value)
else:
data1 = 'NaN'
data2 = 'NaN'
data_str1 = ''.join([extract_column, '=', data1])
data_str2 = ''.join([target_column, '=', data2])
data_list = [data_str1, data_str2]
data_list_str = '\n'.join(data_list)
with open(out_path, 'w') as f:
f.write(data_list_str)
if __name__ == '__main__':
input_path = os.path.join(os.getcwd(), "data.csv")
target_column = "Out"
target_val = 2.5
extract_column = "In"
out_path = 'get_abc.txt'
main()
特記事項は、データ処理過程で、.Tで転置行列で一旦抽出した点である。そうしないとリストのリストとなり、扱いづらいためである。
No In Out abc
1 21 1.200 a
2 32 1.240 b
3 42 1.410 c
4 58 1.720 d
5 91 1.933 e
6 99 2.000 f
7 115 2.220 g
8 132 2.670 h
9 148 2.810 i
10 165 2.910 j
[ 1.2 1.24 1.41 1.72 1.933 2. 2.22 2.67 2.81 2.91 ]
以上
<広告>
リンク