質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
JupyterLab

JupyterLabは、Jupyter notebookの後継の対話型開発環境(IDE)です。データの可視化がインタラクティブで、プラグイン作成により新しいコンポーネントの追加および既存のコンポーネントも統合可能。サーバに閉じているため、データ分析に向いています。

NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

Q&A

解決済

2回答

1098閲覧

算出結果を、for文で回しながら、新しいデータフレームの新たな列に追加する

goichi

総合スコア16

JupyterLab

JupyterLabは、Jupyter notebookの後継の対話型開発環境(IDE)です。データの可視化がインタラクティブで、プラグイン作成により新しいコンポーネントの追加および既存のコンポーネントも統合可能。サーバに閉じているため、データ分析に向いています。

NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

0グッド

0クリップ

投稿2022/01/23 15:04

#課題
Colaboratoryで、データを集めやすい市場・競馬等のデータを収集して、参考になるコードを試しながら、Pythonの勉強をしています。
現在、データの処理結果を、データフレームの新しい列に追加する処理で苦戦しています。
色々試しましたが、自身の力が不足しており、どうしても解決できませんでした。
恐れ入りますが、初学者なこともあり、どのようなコードを、どこに入れればよいのか、ご教示いただきたくお願い申し上げる次第です。

#実現したいこと
①縦向きに出力されるのデータの処理結果(deffの値)を、②別途作成しているデータフレームの背番号(no)に応じて、データフレームの新しい列に横向きに、for文で回しながら追加したい。という内容です。
色々試しましたが、自身の力が不足しており、どうしても解決できませんでした。
恐れ入りますが、初学者なこともあり、どのようなコードを、どこに入れればよいのか、ご教示いただきたくお願い申し上げる次第です。

前提

**#1.データ処理結果
データの処理結果は下表のように、縦向きに、出力されます。
データ処理のコードは下記のソースコード及び参考URLをご参照ください。
イメージ説明

ソースコード①

ソースコードは、https://zenn.dev/moripon/articles/ed5caa9c1d621e
(出所:pyparsingで競馬のコーナー通過順位をパースより引用)

import numpy as np
import pandas as pd
import pyparsing as pp

columns = ['diff', 'horse_no']

DIFF_GROUP = 0.3
DIFF_MIN = 1.5
DIFF_MID = 3.0
DIFF_MUCH = 6.0

class ParsePass():

def __init__(self): horse_no = pp.Word(pp.nums).setParseAction(self._horse_no_action) group = pp.Suppress(pp.Literal('(')) + \ pp.Optional(pp.delimitedList(pp.Word(pp.nums), delim=',')) + \ pp.Suppress(pp.Literal(')')) group.ignore('*') group.setParseAction(self._group_action) element = (group | horse_no) diff_min = pp.Suppress(pp.Optional(pp.Literal(','))).setParseAction(self._diff_min_action) + element diff_mid = pp.Suppress(pp.Literal('-')).setParseAction(self._diff_mid_action) + element diff_much = pp.Suppress(pp.Literal('=')).setParseAction(self._diff_much_action) + element self._passing_order = element + pp.ZeroOrMore( diff_mid | diff_much | diff_min ) def _horse_no_action(self, token): self._data = self._data.append({'diff':self._diff, 'horse_no':token[0]}, ignore_index=True) return def _group_action(self, token): for no in token: self._data = self._data.append({'diff':self._diff, 'horse_no':no}, ignore_index=True) self._diff += DIFF_GROUP self._diff -= DIFF_GROUP return def _diff_min_action(self, token): self._diff += DIFF_MIN return def _diff_mid_action(self, token): self._diff += DIFF_MID return def _diff_much_action(self, token): self._diff += DIFF_MUCH return def parse(self, pass_str): # 初期化 self._data = pd.DataFrame(columns=columns) self._diff = 0 # parse self._passing_order.parseString(pass_str) # index調整 self._data.index = np.arange(1, len(self._data)+1) self._data.index.name = 'rank' return self._data

test data

下は算出結果の出力例です。実際はfor文で回すため、該当のソースコード②を先に実行してから、pass_data =results[1]として出力しています。

if name == 'main':
pass_data = ["(*6,10)11(4,2,9)-(1,5)12,8,14(3,13,15)7-16",
"6(10,11)(4,2,9)(1,5)12(8,14)(3,13,15)7=16",
"12(7,14)8(6,11)9(3,5)(2,10)(1,4,13)",
"12(7,14)8(6,11)9(2,5)(3,1,10)(4,13)",
" (*10,14)-(8,4)-(12,11,9)5(2,1)7,6,13=3",
"(10,*14)-(8,4)-(11,1)2,9,5,6-(7,13)-12-3"]

pass_parsing = ParsePass()
pass_str in pass_data:
print(pass_parsing.parse(pass_str))

実現したいこと

現在、競技ID、最終順位、背番号、各通過地点のrankをpandasのデータフレーム(以下、現データフレーム)に格納しています。
実現したいことは、下表上段(黄色)の現データフレームの背番号(no)毎に、上述#1のデータ処理結果のnoに合致するdeffの数値(表の真中の列の数値)を抽出して、競技IDをKeyとしてfor文で回しながら、現データフレームの新しい列に横向きにdeffの数値を加えていきたいです(下図の緑色箇所)

イメージ説明

できたこと、できないこと
<できたこと>
競技IDをKeyとして、for文を回しながら、各地点の通過順位(rank)を取得すること、競技IDをKeyとして、for文を回しながら、#1の処理結果を出力することはできました。
<できないこと>
出力結果から①deffの数値が取り出せないこと、②現データフレームの競技ID、背番号(no)に応じて、deffの数値を現データフレームの新しい列に追加するためのfor文が書けませんでした。

なお、競技IDをKeyとしてfor文で回すために以下のコードを利用しています。
本ソースコードを先に実行してから、上述のソースコード①のtest dataにおいて、pass_data =results[1]として出力する。このコードの最後のresultsにあたります。
どうぞよろしくお願いいたします。

ソースコード②

import pandas as pd import time from tqdm import tqdm def scrape_race_results(race_id_list, pre_race_results={}): race_results = pre_race_results.copy() for race_id in tqdm(race_id_list): if race_id in race_results.keys(): continue try: url="https://db.netkeiba.com/race/" + race_id race_results[race_id] = pd.read_html(url)[4] time.sleep(1) except IndexError: continue except Exception as e: print(e) break except: break return race_results race_id_list=[] for place in range(1,11,1): for kai in range(1,6,1): for day in range(1,13,1): for r in range(1,13,1): race_id="2021"+str(place).zfill(2)+str(kai).zfill(2)+str(day).zfill(2)+str(r).zfill(2) race_id_list.append(race_id) test3 = scrape_race_results(race_id_list) for key in test3: test3[key].index = [key]*len(test3[key]) results = pd.concat([test3[key] for key in test3],sort=False)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

現在、競技ID、最終順位、背番号、各通過地点のrankをpandasのデータフレーム(以下、現データフレーム)に格納しています。

このデータフレームを contest とします。

python

1 競技ID 最終順位 背番号 通過地点3rank 通過地点4rank 20 202101010101 1 1 7 7 31 202101010101 2 3 12 12 42 202101010101 3 2 5 5 53 202101010101 4 5 8 8 64 202101010101 5 4 4 4 75 202101010101 6 15 14 14

以下では pandas.DataFrame.merge を使用して left join を行っています。

python

1if __name__ == '__main__': 2 pass_data = [ 3 "(*6,10)11(4,2,9)-(1,5)12,8,14(3,13,15)7-16", 4 "6(10,11)(4,2,9)(1,5)12(8,14)(3,13,15)7=16", 5 "12(7,14)8(6,11)9(3,5)(2,10)(1,4,13)", 6 "12(7,14)8(6,11)9(2,5)(3,1,10)(4,13)", 7 " (*10,14)-(8,4)-(12,11,9)5(2,1)7,6,13=3", 8 "(10,*14)-(8,4)-(11,1)2,9,5,6-(7,13)-12-3" 9 ] 10 11 pass_parsing = ParsePass() 12 for i, pass_str in enumerate(pass_data): 13 df = pass_parsing.parse(pass_str) 14 df['horse_no'] = df['horse_no'].astype(int) 15 contest = ( 16 contest 17 .merge(df, left_on='背番号', right_on='horse_no', how='left') 18 .iloc[:,:-1] 19 .rename(columns={'diff': f'通過{i+1}距離'})) 20 21 print(contest) 22 23# 24 競技ID 最終順位 背番号 通過地点3rank 通過地点4rank 通過1距離 通過2距離 通過3距離 通過4距離 通過5距離 通過6距離 250 202101010101 1 1 7 7 6.9 5.4 11.7 10.2 10.5 6.9 261 202101010101 2 3 12 12 13.2 10.5 8.1 9.9 21.0 22.2 272 202101010101 3 2 5 5 3.6 3.6 9.9 8.1 10.2 8.4 283 202101010101 4 5 8 8 7.2 5.7 8.4 8.4 8.7 11.4 294 202101010101 5 4 4 4 3.3 3.3 12.0 12.0 3.6 3.6 305 202101010101 6 15 14 14 13.8 11.1 NaN NaN NaN NaN

投稿2022/01/23 16:59

melian

総合スコア19618

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

丁寧なご回答ありがとうございました。最初に、私のご説明が不十分であったことについて、心よりお詫び申し上げます。
さて、教えていただいたコードで、データを増やして試してみたのですが、意図しない数字がでてきたり、意図せず列が増えてしまう状況です。しかしながら、今までよりは、大きく前に進んだ手応えを感じております。
力不足ですが、説明資料を整えました。
お手数おかけいたしますが、ご助力賜りたく謹んでお願い申し上げます。

1.現状の概観
①新たな、背番号を含むデータフレームを作成済み、通過地点の距離を算出するためのデータを取得済み
②通過地点毎の距離と背番号を算出することができる。(コードは参考コードを利用。pyparsingで競馬のコーナー通過順位をパースより)
https://zenn.dev/moripon/articles/ed5caa9c1d621e

③通過地点の通過距離の表に基づいて、各背番号の通過地点毎の距離(diff)の値を取り出すことができない。また、取り出した値を作成済みのデータフレームに追加することができない。

(現状の概観について)
イメージ説明

(一部拡大)
イメージ説明

2実現したいこと詳細
既存のデータフレームに4列追加して、②for文で回しながら、③背番号(左橙色囲み)の行に、通過地点の通過距離の表に基づいて、各背番号の通過地点毎の距離diffの値を入力したいです。
実現したいことの詳細は次のとおりです。

(実現したいことの詳細について)
イメージ説明

(一部を拡大)
イメージ説明

(一部を拡大)
イメージ説明

(説明詳細を拡大)
イメージ説明
不足点がありましたらなんなりとお申し付けください。

投稿2022/01/24 01:13

編集2022/01/24 14:35
goichi

総合スコア16

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

melian

2022/01/25 04:49

ベストアンサーに選んでいただき、どうもありがとうございます。今回の質問ですが、回答として投稿されていますので、おそらく閲覧しているのは私だけかと思います。なので、他の回答者の目にも触れる様に新規の質問として投稿してみてはどうでしょうか。
goichi

2022/01/25 08:58

承知いたしました。ご丁寧にありがとうございます。
goichi

2022/01/26 08:09

今般は丁寧なご指導いただきありがとうございました。 いただいたアドバイスを踏まえ、資料を整理し、一部前提条件を変更したうえで、新規の質問として投稿しました。 「出力結果から値を抽出して、データフレームの新しい列に反映したい」です。 ご多忙の折、大変恐縮ですが、再度のご支援を賜りたく謹んでお願い申し上げます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問