[Python] 234 複数のCSVファイル内検索 馬名からレース検索 リスト内包表記

一番時間の掛かるraceID検索のところをリスト内包表記で書いてみました。

そもそもopen文を組み込むことができるのか懐疑的だったものの、あっさり書けました。こんなややこしいのを共同開発の現場で見せられたらたまりませんね。

残念ながら時間短縮はならずです。C言語で書いてもそんなに変わらなさそうですが、短いコードなので検討してみても面白そうです。

元コード for文
--------------------------------------------------
raceID_l = list()
for y in range(start_year,2021 +1):
    for file in glob.glob(f'/horse_racing/race_result/{y}/*/*/*.csv'):
        with open (file, mode="r", encoding="shift_jis") as f:
            reader = csv.reader(f)
            for row in reader:
                if row[22] == id:
                    raceID_l.append(row[21])
--------------------------------------------------

リスト内包表記
--------------------------------------------------
raceID_l = [row[21] for y in range(start_year,2021 +1) \
for file in glob.glob(f'/horse_racing/race_result/{y}/*/*/*.csv') \
for row in csv.reader(open(file,mode="r", encoding="shift_jis")) \
if row[22]==id]
--------------------------------------------------

[Python] 233 複数のCSVファイル内検索 馬名からレース検索 高速化

前回のコードは見るからに効率の良くなさそうな内容だったので書き直しました。

pandasはやめてcsvモジュールで処理しました。

その結果、80秒が5秒に短縮されました。やはりこの種の処理にpandasを使うのはナンセンスだったようです。

この速さなら本式のデータベースにする程でもないように思いますが、迷うところです。

import glob,csv,re,datetime

print('検索したい馬名を入力してください')
name = input()

horseID_l = list()
for year in range(1986,2019 +1):
    for file in glob.glob(f'/Volumes/DATA_HR/horse_racing/horse_list/horse{year}.csv'):
        with open (file, mode="r", encoding="shift_jis") as f:
            reader = csv.reader(f)
            for row in reader:
                if row[1] == name:
                    horseID_l.append([row[0],row[1]])

print(f'{horseID_l}')

if len(horseID_l) >= 2:
    print('該当する馬が複数います。番号を入力してください。')
    for i,data in enumerate(horseID_l):
        print(f'{i+1} {data}')
    num = input()
    id = horseID_l[int(num)-1][0]

elif len(horseID_l) == 0:
    print('該当する馬はいません')
    sys.exit()

else:
    id = horseID_l[0][0]

print(f'検索馬のID {id} 誕生年 {id[0:4]}')

raceID_l = list()
start_year = int(id[0:4]) + 2
print(f'推定デビュー年 {start_year}')
for y in range(start_year,2021 +1):
    for file in glob.glob(f'/horse_racing/race_result/{y}/*/*/*.csv'):
        with open (file, mode="r", encoding="shift_jis") as f:
            reader = csv.reader(f)
            for row in reader:
                if row[22] == id:
                    raceID_l.append(row[21])

print(raceID_l)

race_l = list()
for id in raceID_l:
    for y in range(start_year,2021 +1):
        for file in glob.glob(f'/horse_racing/race_name/{y}/*.csv'):
            with open (file, mode="r", encoding="shift_jis") as f:
                reader = csv.reader(f)
                for row in reader:
                    if row[9] == id:
                        date = row[0]
                        racename = row[3]
                        date_dt = datetime.datetime.strptime(date,'%Y年%m月%d日')
                        date_d = datetime.date(date_dt.year, date_dt.month, date_dt.day)

                        race_l.append([id,date,racename,date_d])

print(f'出走数 {len(race_l)}')
print(sorted(race_l, key=lambda x: x[3]))

[Python] 232 複数のCSVファイル内検索 馬名からレース検索 修正版

[Python] 231のコードを修正しました。

これでキタサンブラックの全20走が抽出できました。

修正前
--------------------------------------------------
b_array = df[df.columns[22]]== id
--------------------------------------------------

修正後
--------------------------------------------------
id_l = df[df.columns[22]].tolist()

if '該当なし' in id_l:
    b_array = df[df.columns[22]]== str(id)
else:
    b_array = df[df.columns[22]]== id
--------------------------------------------------

出力
--------------------------------------------------
検索したい馬名を入力してください
キタサンブラック
year 2012 index 3012
キタサンブラック [[2012, 201202013, 'キタサンブラック']]
検索馬のID 201202013 誕生年 2012
推定デビュー年 2014
['r201505010105', 'r201505010807', 'r201505021210', 'r201506020811', 'r201506030811', 'r201506040511', 'r201506050810', 'r201508040711', 'r201605050811', 'r201606050910', 'r201608030411', 'r201608040311', 'r201609020411', 'r201609030811', 'r201705040911', 'r201705050811', 'r201706050811', 'r201708030411', 'r201709020411', 'r201709030811']
出走数 20
[['r201505010105', '2015年1月31日', '3歳新馬', datetime.date(2015, 1, 31)], \
['r201505010807', '2015年2月22日', '3歳500万下', datetime.date(2015, 2, 22)], \
['r201506020811', '2015年3月22日', '第64回フジTVスプリングS(G2)', datetime.date(2015, 3, 22)], \
['r201506030811', '2015年4月19日', '第75回皐月賞(G1)', datetime.date(2015, 4, 19)], \
['r201505021210', '2015年5月31日', '第82回東京優駿(G1)', datetime.date(2015, 5, 31)], \
['r201506040511', '2015年9月21日', '第69回朝日セントライト記念(G2)', datetime.date(2015, 9, 21)], \
['r201508040711', '2015年10月25日', '第76回菊花賞(G1)', datetime.date(2015, 10, 25)], \
['r201506050810', '2015年12月27日', '第60回有馬記念(G1)', datetime.date(2015, 12, 27)], \
['r201609020411', '2016年4月3日', '第60回産経大阪杯(G2)', datetime.date(2016, 4, 3)], \
['r201608030411', '2016年5月1日', '第153回天皇賞(春)(G1)', datetime.date(2016, 5, 1)], \
['r201609030811', '2016年6月26日', '第57回宝塚記念(G1)', datetime.date(2016, 6, 26)], \
['r201608040311', '2016年10月10日', '第51回京都大賞典(G2)', datetime.date(2016, 10, 10)], \
['r201605050811', '2016年11月27日', '第36回ジャパンカップ(G1)', datetime.date(2016, 11, 27)], \
['r201606050910', '2016年12月25日', '第61回有馬記念(G1)', datetime.date(2016, 12, 25)], \
['r201709020411', '2017年4月2日', '第61回大阪杯(G1)', datetime.date(2017, 4, 2)], \
['r201708030411', '2017年4月30日', '第155回天皇賞(春)(G1)', datetime.date(2017, 4, 30)], \
['r201709030811', '2017年6月25日', '第58回宝塚記念(G1)', datetime.date(2017, 6, 25)], \
['r201705040911', '2017年10月29日', '第156回天皇賞(秋)(G1)', datetime.date(2017, 10, 29)], \
['r201705050811', '2017年11月26日', '第37回ジャパンカップ(G1)', datetime.date(2017, 11, 26)], \
['r201706050811', '2017年12月24日', '第62回有馬記念(G1)', datetime.date(2017, 12, 24)]]
--------------------------------------------------