如何拆分DataFrame中PGN列的国际象棋数据并提取字段与走法
拆分Chess.com对局PGN数据为结构化列与走法内容
你可以通过扩展现有代码,添加PGN解析逻辑,实现将元数据拆分为独立列、提取走法的需求。以下是具体实现方案:
完整修改后的代码
import chessdotcom import pandas as pd import regex as re import json from io import StringIO def parse_pgn(pgn_text): # 提取PGN中的元数据(如Event、Site、Date等) meta_pattern = re.compile(r'\[(\w+) "([^"]+)"\]') meta_data = dict(meta_pattern.findall(pgn_text)) # 提取对局走法:移除元数据块,清理结尾的结果标记(如1-0、*) moves_part = re.sub(r'\[.*?\]\n', '', pgn_text).strip() moves_clean = re.sub(r'\s*(1-0|0-1|\*)$', '', moves_part).strip() meta_data['moves'] = moves_clean return pd.Series(meta_data) def cleandata(datacall): data = datacall.text x = json.loads(data) df = pd.read_json(StringIO(json.dumps(x))) df2 = pd.json_normalize(df['games']) # 解析PGN列,拆分元数据和走法 pgn_parsed = df2['pgn'].apply(parse_pgn) # 合并原数据与解析后的PGN信息,移除原始pgn列 df_final = pd.concat([df2.drop('pgn', axis=1), pgn_parsed], axis=1) df_final.to_csv(r'chessdataframegamesv3.csv', index=False) return df_final # 获取对局数据并处理 datacall = chessdotcom.client.get_player_games_by_month("Player1", 2022, 7) final_df = cleandata(datacall)
代码说明
parse_pgn函数:- 用正则匹配PGN中
[Key "Value"]格式的元数据,将其转换为键值对字典 - 移除元数据块后,清理走法内容中的结果标记(如对局结束的
1-0或*),提取纯走法文本存入moves字段 - 返回Series,方便与原DataFrame合并
- 用正则匹配PGN中
cleandata函数扩展:- 对
df2中的pgn列批量应用parse_pgn解析,得到包含元数据列和走法列的DataFrame - 将解析结果与原数据合并,移除原始
pgn列,最终保存为结构化的CSV
- 对
可选:拆分走法为单行记录
如果需要将每一步走法单独作为一行记录(保留对局其他元数据),可以在cleandata函数末尾添加以下代码:
# 拆分走法为单行记录 df_moves = df_final.assign(move=df_final['moves'].str.split()).explode('move').reset_index(drop=True) # 保存为单独的走法CSV df_moves.to_csv(r'chessdataframe_moves.csv', index=False)
这段代码会将moves列按空格拆分为单个走法,然后通过explode展开,生成每行对应一步走法的DataFrame。
内容的提问来源于stack exchange,提问作者beardedgardener
相关产品推荐
相关产品推荐

