実現したいこと
Python初心者です。
Pythonを使用してcsvデータを読み込み、それを分析するためのプログラムを作成中です。
実現したいことは作成したプログラムを条件によって続けるか分岐させるため、def main、while文にてループさせたいのですが、def main内でのインスタンス化等がうまくできません。
発生している問題・分からないこと
実際のコードはあまりにも長すぎるため、ここでは問題点を解決するための簡易にしたコードを貼らせていただきます。一番の問題はクラス「TestData2」内で実際のコードでは「df_test」にあたるデータフレームの変数が複数存在しており、def main内でインスタンス化や元々のコードの最後の部分をそのまま移行すると、「df_test」に当たる部分が定義されていませんとエラーになっています。しかし一部だけをdef main外(def mainの前で定義)すると文字変換エラー等がでてしまいます。(おそらくTestDeta1の変換がうまくいかなくなってしまっているため)。「df_test」を「self.df_test」にしてみたこともあるのですが、あまりにもエラーが多発したのと、できればグローバル変数にするのも避けたいです。
該当のソースコード
import chardet import pandas as pd import numpy as np import datetime from datetime import datetime, timedelta class TestData1: def __init__(self, file_path): self.state = 'initial' # 初期状態 self.file_path = file_path self.df_test = None # 初期化 def load_data(self): with open(self.file_path, 'rb') as f: binary = f.read() d = chardet.detect(binary) if d["encoding"] == "utf-8": enco = "utf-8" elif d["encoding"] == "UTF-8-SIG": enco = "utf_8_sig" else: enco = "SHIFT-JIS" self.df_test = pd.read_csv(self.file_path, encoding=enco, header=None, usecols=range(44), skiprows=[0], nrows=301) return self.df_test def convert_data_types(self): self.df_test.iloc[0:1, 0:44] = self.df_test.iloc[0:1, 0:44].astype(str) self.df_test.iloc[1:301, 0] = pd.to_datetime(self.df_test.iloc[1:301, 0], format='%H:%M:%S', errors='coerce').dt.time self.df_test.iloc[1:301, 41] = pd.to_datetime(self.df_test.iloc[1:301, 41], format='%H:%M:%S', errors='coerce').dt.time self.df_test.iloc[1:301, 1:41] = self.df_test.iloc[1:301, 1:41].astype(float) self.df_test.iloc[1:301, 42:44] = self.df_test.iloc[1:301, 42:44].astype(float) def print_data(self): print(self.df_test) print("Class1実行完了") self.state = 'updated' # インスタンス変数を更新 # クラスのインスタンスを作成 data_test1 = TestData1("C:\\Users\\PC_User\\Desktop\\test_csv\\Sheet1.csv") df_test = data_test1.load_data() data_test1.convert_data_types() data_test1.print_data() class TestData2: def __init__(self, df_test): self.state = 'initial' # 初期状態 self.df_test = df_test self.label_dict = {} self.test1 = None # 初期化 self.test2 = float('-inf') def process_label_test(self,label): if label in self.label_dict: top_row = self.label_dict[label][0] time = df_test.iloc[top_row-2, 41] time_plus_one_sec = (datetime.combine(datetime.date.today(), time) + timedelta(seconds=1)).time() closest_time_row = self.df_test.iloc[(self.df_test.iloc[1:301,0].apply(lambda x: x.hour*3600 + x.minute*60 + x.second) - (time_plus_one_sec.hour*3600 + time_plus_one_sec.minute*60 + time_plus_one_sec.second)).abs().argsort()[:1]] self.test1 = closest_time_row.iloc[0, 11] def label_answer_test(self): for label in ['A', 'B', 'C', 'D', 'E', 'F']: result = self.process_label_test(label) if result == self.test1: print("成功") print("Class2実行完了") self.state = 'updated' # インスタンス変数を更新 # クラスのインスタンスを作成 deta_test2 = TestData2(df_test) deta_test2.label_answer_test() class TestData3: def __init__(self): self.state = 'initial' # 初期状態 def test_3(self): print("test3実行") self.state = 'noneupdated' # インスタンス変数を更新 print("Class3実行完了") 以上の文をループさせるため、各コードの「#クラスのインスタンスを作成」の部分を下記のコードにうまく当てはめたいです。 # ループ文を作成 def main(): class1_instance = TestData1() class2_instance = TestData2() class3_instance = TestData3() while class3_instance.state != 'updated': class1_instance.load_data() class1_instance.convert_data_types() class1_instance.print_data() class2_instance.process_label_test() class2_instance.label_answer_test() class3_instance.test_3() break print("Done!") if __name__ == "__main__": main()
試したこと・調べたこと
- teratailやGoogle等で検索した
- ソースコードを自分なりに変更した
- 知人に聞いた
- その他
上記の詳細・結果
いくつか試しましたがエラーを解決することができませんでした。何卒宜しくお願い致します。
補足
特になし