[Python] 283 C言語実行ファイルの併用 その3 若干の時間短縮

前回の続きです。

どう考えても検索ヒットした馬名のデータが2行になるのは無駄なので、1行になるよう修正しました。

この修正により処理時間が87秒から80秒に短縮されました。

<修正箇所>

while(fgets(buf,2000, fp ) != NULL ) {
    sscanf(buf, " %9s, %[^,], %[^,], %[^,], %[^,], %[^,], %[^,], %[^,], %[^,], %[^,], %[^,], %[^,], %[^,], %[^,], %[^,], %[^,], %s",horseID,horse_name,horse_name0,status,gender,hair,birthday,trainer,owner,info,breeder,area,price,prize_money,result,wining_race,relatives ) ;

    if (i != 0){
        if (strcmp(horse_name,horse_name_in)==0){
	        fp3 = fopen(fname3, "a");
	        fprintf(fp3, "%s,%9s\n", horse_name,horseID);
	        fclose(fp3);
	        b ++;
	        break;
        }
    }
    i ++ ;
}
if (b == 0){
	fp3 = fopen(fname3, "a");
	fprintf(fp3, "%s,100000000\n", horse_name_in);
	fclose(fp3);
}

[Python] 282 C言語実行ファイルの併用 その2 内容説明

前回の続きです。

C言語実行から作成したデータを処理する流れを説明します。

実行ファイルはsubprocessモジュールで走らせて、処理の終了は実行ファイルの最後に仕込んだ標準出力の受け取りで判断します。

作成されたデータ内容は下図のようになっています。データベースにヒットした馬名は2行になり、ヒットしなかった馬名は1行になります。

あとはpandasなどを使ってデータ加工するのですが、重複行の削除には一工夫必要でした。馬名は複数回登場することがあるのでpandasのduplicatedメソッドは使えず、馬名列要素のリストと1要素分スライドしたリストを比較し重複する所のインデックス番号をリスト化して処理しました。

重たい処理はC言語にさせて、出来上がったラフなデータをPythonで加工する。データベースを扱うに際し私にとって最強の組み合わせになりそうです。

<該当箇所のみ>

# C言語実行ファイル
proc = subprocess.run(C言語実行ファイルのパス, shell=True, stdout= subprocess.PIPE, stderr = subprocess.PIPE)
print(proc.stdout.decode('UTF-8'))

# horseID.csvのデータフレーム化
df = pd.read_csv(horseID_file,names=['馬名2','horseID'],encoding='UTF-8')

# "馬名2"列リストと1要素スライドしたリストを作成(最後の'A'は数合わせ)
list_horseA = df['馬名2'].tolist()
list_horseB = list_horseA[1:] + ['A']

# 重複行のインデックス番号を取得してリスト化
list_num = []
i = 1
for nameA,nameB in zip(list_horseA,list_horseB):
    if nameA == nameB:
        list_num.append(i)
    i = i + 1

# 重複行を削除
df2 = df.drop(df.index[list_num])