DX(デジタルトランスフォーメーション)
前回、PythonではじめるなんちゃってDXとして、Y軸が2つのグラフを作成するプログラムを紹介しました。

今回はデータ形式を前に作成したグラフ作成プログラムに合わせるためのプログラムを紹介します。
どういうことかというと、前回使用したグラフ作成プログラムに読み込ませるデータはこんな感じでした。
(CSVファイルなので、テキストエディタで開くとカンマ区切りです)

つまり1行目にそれぞれのデータの名前(X軸かY軸かの識別は不要)で、2行目からその値のデータが下に並んでいる形式です。
グラフ作成プログラムではこの形式のデータしか読み込めません。
ただ測定器などからデータを取得した場合、そのデータを取得した日時や条件など、付加的な情報が記載されていたり、それぞれの行にデータのタグが付けられているなんてことがあります。
ということでそのフォーマットの違いを直し、グラフ作成プログラムが読み込める形のデータにしなければいけません。
今回はデータの前にある付加的な情報が含まれている場合に、目的の数値データを抜き出すプログラムを作成してみたので紹介します。
このプログラムでできること
このプログラムでできることは「付加情報が含まれているCSVファイルから数値データを抜き出すこと」です。
準備するデータはこんな感じです。
(CSVファイルなので、テキストエディタで開くとカンマ区切りです)

最初に「Measurement time」として測定日時があり、「Mode」とか「Condition」とかが付加的な情報(ここではダミーですが)です。
そしてグラフ作成に必要なデータとしては、「Time Value1」以降のデータになります。
ということで出てくるデータとしてはこんな感じです。

ここまでできれば、前に作成したグラフ作成プログラムに読み込ませ、グラフを表示することができるというわけです。
使い方
まずはこちらのファイルをダウンロードして、展開してください。
展開すると「dx-4_FileConvertor1.py」と「dx-4_settings.txt」というファイルが出てきます。
この二つのファイルを処理したいファイル(下の例ではdx-4_Data1.csvとdx-4_Data2.csv)と同じフォルダに置いてください。

次に「dx-4_settings.txt」を開きます。

ここに取得したい数値データの一番最初の列名を入力します。
つまり先ほどのデータの中ではこの「Time」です。

テキストエディタの表示でみるとここになります。

このプログラムではこの指定した「数値データの最初の列名」を手がかりに、それ以降のデータを抽出します。
そのため、あまりないですが、もし下に付加的な情報がある場合はそれも一緒に抜き出されてしまうのに注意してください。
これで設定は完了ですが、処理したいファイルの名前に制限があり、ファイル名の最初に「dx-4_」をつけてください。
「dx-4_」が付いていないと処理されません。
準備ができたら、「dx-4_FileConvertor1.py」を実行します。
ダブルクリックで実行してもいいですし、ターミナルやコマンドプロンプトからこちらのコマンドを実行してもいいです。
python dx-4_FileConvertor1.py
実行するとこんな感じになります。

ちなみに「このウインドウは10秒後に自動で閉じますので、そのままお待ちください。」とありますが、Macでは自動で閉じないようです。
ここら辺はご愛嬌ということで、各自で閉じてください。
これで最初に同じフォルダに置いたデータそれぞれに対し、「日時_ファイル名.txt」と「日時_ファイル名.csv」が生成されます。

「日時_ファイル名.txt」は元のファイルの付加情報の部分です。
つまり指定した行よりも上の情報がこちらに出力されます。

「日時_ファイル名.csv」が数値データのファイルです。

上記の例では値は2列ですが、3列でももしくはそれ以上でも抽出することができます。


プログラムの解説
プログラム全体
それではプログラムの解説をしていきます。
プログラム全体としてはこんな感じです。
import os
import datetime
import time
def filenameGet():
csv_list = []; text_list =[]
for filename in os.listdir('./'):
if filename.startswith('dx-4_'):
if filename.endswith('.csv'):
csv_list.append(filename[:-4])
elif filename == 'dx-4_settings.txt':
text_list.append(filename)
return csv_list, text_list
def fileProcess(csv_list, text_list, timenow):
start_label=''
for text in text_list:
with open(f'./{text}') as f_in:
for row in f_in:
start_label = row
break
if start_label == '':
print('データ開始位置の文字列がありません。')
print('dx-4_settings.txtにデータ開始位置のラベルを記入してください。(1行目のみ有効)')
print('処理を中止します。')
else:
print(f'{start_label}以降の値を取得します。')
for csv in csv_list:
flag = 0; settings_data = []; value_data = []
print(f'{csv}を処理します。')
with open(f'./{csv}.csv', 'r') as f_in:
for row in f_in:
if row.startswith(start_label):
flag = 1
value_data.append(row)
elif flag == 0:
settings_data.append(row)
elif flag == 1:
value_data.append(row)
with open(f'{timenow}_{csv}.txt', 'w') as f_out:
for row in settings_data:
f_out.write(row)
print(f'{csv}の{start_label}以前のデータをdx-4_{timenow}.txtに保存しました。')
with open(f'{timenow}_{csv}.csv', 'w') as f_out:
for row in value_data:
f_out.write(row)
print(f'{csv}の{start_label}以降のデータをdx-4_{timenow}.csvに保存しました。')
def main():
timenow = timenow = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
csv_list, text_list = filenameGet()
print(f'CSVファイル:{csv_list}')
print(f'TEXTファイル:{text_list}')
fileProcess(csv_list, text_list, timenow)
print('このウインドウは10秒後に自動で閉じますので、そのままお待ちください。')
time.sleep(10)
if __name__ == '__main__':
main()
「filenameGet関数」は前に解説していますので、今回は解説をスキップします。
ライブラリのインポート
今回使用するライブラリは「os」、「datetime」、「time」です。
import os
import datetime
import time
これらは元々Pythonに含まれるライブラリ(標準ライブラリ)なので今回は何もインストールする必要はありません。
fileProcess関数
ファイルを処理するための関数です。
処理が大きく3つに分かれているので、別々に見ていきましょう。
fileProcess関数 その1:データの区切り位置の取得
fileProcess関数 その1は「dx-4_settings.txt」からデータの区切り位置を取得する部分です。
start_label=''
for text in text_list:
with open(f'./{text}') as f_in:
for row in f_in:
start_label = row
break
if start_label == '':
print('データ開始位置の文字列がありません。')
print('dx-4_settings.txtにデータ開始位置のラベルを記入してください。(1行目のみ有効)')
print('処理を中止します。')
else:
print(f'{start_label}以降の値を取得します。')
「dx-4_settings.txt」を開き、1行目だけ読み込み、その値を「start_label」に格納しています。
そしてもし「dx-4_settings.txt」に何も書かれていない場合は、エラーを表示し、処理を終了させます。
「start_label」が空でなかった場合は、その旨を表示し、続く処理を行います。
fileProcess関数 その2:データの抽出
fileProcess関数 その2からデータを抽出する部分です。
for csv in csv_list:
flag = 0; settings_data = []; value_data = []
print(f'{csv}を処理します。')
with open(f'./{csv}.csv', 'r') as f_in:
for row in f_in:
if row.startswith(start_label):
flag = 1
value_data.append(row)
elif flag == 0:
settings_data.append(row)
elif flag == 1:
value_data.append(row)
今回はフラッグ(flag)を使って抽出するかどうかを決めることにしました。
まずはflagという値を「0」に設定します(flag = 0)。
CSVファイルを開き(with open(f’./{csv}.csv’, ‘r’) as f_in:)、1行ずつ読み込みます(for row in f_in:)。
そして行の最初が「dx-4_settings.txt」より取得した文字列と一致した場合(if row.startswith(start_label):)で条件分岐させます。
この条件に一致した時に、flagの値を「1」に変えます。
flagの値が「0」の場合(elif flag == 0:)、その行のデータを「settings_data」に格納します(settings_data.append(row))。
またflagの値が「1」の場合(elif flag == 1:)、その行のデータを「value_data」に格納します(value_data.append(row))。
この「settings_data」と「value_data」は後に付加情報として出力するためのリストとデータを出力するためのリストです。
fileProcess関数 その3:データの出力
最後はデータの出力部分です。
with open(f'{timenow}_{csv}.txt', 'w') as f_out:
for row in settings_data:
f_out.write(row)
print(f'{csv}の{start_label}以前のデータをdx-4_{timenow}.txtに保存しました。')
with open(f'{timenow}_{csv}.csv', 'w') as f_out:
for row in value_data:
f_out.write(row)
print(f'{csv}の{start_label}以降のデータをdx-4_{timenow}.csvに保存しました。')
「settings_data」も「value_data」もリスト形式で格納してあるので、それを一つずつ取得し、ファイルに書き込んでいます。
main関数
main関数ではfilenameGet関数とfileProcess関数を実行しています。
def main():
timenow = timenow = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
csv_list, text_list = filenameGet()
print(f'CSVファイル:{csv_list}')
print(f'TEXTファイル:{text_list}')
fileProcess(csv_list, text_list, timenow)
print('このウインドウは10秒後に自動で閉じますので、そのままお待ちください。')
time.sleep(10)
if __name__ == '__main__':
main()
注意すべき点
注意すべき点は以下の通りです。
- 処理できるのはCSVファイルのみ
- CSVファイルの形式が制限
- WindowsとMacでは改行コード(Macでは「\n」)が違う可能性
これはほぼ今まで通りの内容で、特に変わりはありません。
ただ重要なのは2つ目の「CSVファイルの形式が制限」というところです。
今回はデータの前に付加情報があるパターンのデータを処理するプログラムを紹介しました。
ですが、そのほかにもそれぞれの行の頭にタグをつけた形のデータもよく見かけます。
ということで次の機会には別のファイル形式のデータを変換するプログラムを紹介したいと思います。
次回は今回使用したデータを作成するプログラムを紹介します。

ではでは今回はこんな感じで。
コメント