我有一些数据(如下所示),它是字典嵌套列表的字典。 我想把整个字典排成一行。很宽的一排。 目前我已经可以得到我想要的结果了。它很长而且不太优雅。 我想更好地编写更简洁的代码,并希望代码计算效率更高。
就上下文而言,我正在为一个大学项目做这个。我们并没有在代码优雅或优化方面得到标记。这更多是为了我自己的利益。
对 python 来说还是个新手,我不太擅长使用字典的嵌套字典和嵌套字典列表。 任何帮助将不胜感激!
数据字典
{'attack': [{'stat': 'carries_crossed_gain_line', 'value': '52'},
{'stat': 'carries_metres', 'value': '648'},
{'stat': 'carries_not_made_gain_line', 'value': '64'},
{'stat': 'clean_breaks', 'value': '21'},
{'stat': 'defenders_beaten', 'value': '25'},
{'stat': 'offload', 'value': '16'},
{'stat': 'passes', 'value': '168'},
{'stat': 'runs', 'value': '138'},
{'stat': 'turnovers_conceded', 'value': '16'}],
'defence': [{'stat': 'missed_tackles', 'value': '32'},
{'stat': 'tackles', 'value': '125'},
{'stat': 'turnovers_won', 'value': '6'}],
'discipline': [{'stat': 'penalties_conceded', 'value': '12'},
{'stat': 'red_card_second_yellow', 'value': '0'},
{'stat': 'red_cards', 'value': '0'},
{'stat': 'yellow_cards', 'value': '0'}],
'kicking': [{'stat': 'conversion_goals', 'value': '3'},
{'stat': 'kicks_from_hand', 'value': '10'},
{'stat': 'missed_conversion_goals', 'value': '1'},
{'stat': 'missed_penalty_goals', 'value': '0'},
{'stat': 'penalty_goals', 'value': '2'}],
'breakdown': [{'stat': 'mauls_lost', 'value': '0'},
{'stat': 'mauls_total', 'value': '6'},
{'stat': 'mauls_won', 'value': '6'},
{'stat': 'mauls_won_penalty', 'value': '1'},
{'stat': 'mauls_won_try', 'value': '0'},
{'stat': 'rucks_lost', 'value': '11'},
{'stat': 'rucks_total', 'value': '99'},
{'stat': 'rucks_won', 'value': '88'}],
'lineouts': [{'stat': 'lineout_success', 'value': '0.93'},
{'stat': 'lineout_won_steal', 'value': '1'},
{'stat': 'lineouts_Lost', 'value': '1'},
{'stat': 'lineouts_won', 'value': '14'}],
'scrums': [{'stat': 'scrums_lost', 'value': '0'},
{'stat': 'scrums_success', 'value': '1.00'},
{'stat': 'scrums_won', 'value': '2'}],
'possession': [{'stat': 'possession', 'value': '0.50'},
{'stat': 'pc_possession_first', 'value': '0.50'},
{'stat': 'pc_possession_second', 'value': '0.50'},
{'stat': 'ball_possession_last_10_mins', 'value': '0.61'}]}
我尝试过的 我创建了一个函数,可以用来调用每个嵌套 DF,如下所示:
def trim(df):
x = df.transpose()
x.columns = x.iloc[0]
x = x[1:]
return x
我这样称呼。将最后一次“攻击”更改为其他统计数据:
trim(pd.DataFrame(results['home']['team_stats']['attack']))
然后我
这很耗时。有没有一种方法可以让我以更有效或Pythonic的方式做到这一点? 我的最终目标是收集主队和客队的比赛数据(因此将数据框宽度加倍)并每场比赛一行。
额外数据供参考 结果:我只对 ['match']、['home'] 和 ['away'] 字典感兴趣。 在主客场词典中,“team_stats”部分是我试图提取的内容。 该数据来自 API。我首先将响应转换为 json 格式。 每场比赛我都会处理一组这样的数据。目标是进行大约 250 场以上的比赛。
试试这个:
# Assuming `rugby_data`` is the deserialized JSON object from your sample input
df = (
pd.DataFrame(
# The idea is to convert rugby_data to a list of 3-tuples:
# [
# ("match", "id", 3195835),
# ("match", "comp_id", 2142),
# ...
# ("home", "carries_crossed_gain_line", "52"),
# ("home", "carries_metres", "648"),
# ...
# ("away", "carries_crossed_gain_line", "59"),
# ("away", "carries_metres", "561"),
# ...
# ]
[("match", key, value) for key, value in rugby_data["match"].items()]
+ [
(side, stat["stat"], stat["value"])
for side in ["home", "away"]
for _, stats in rugby_data[side]["team_stats"].items()
for stat in stats
],
columns=["category", "key", "value"],
)
# Then transform it to a wide format
.set_index(["category", "key"])
.T
)
# Your stats are all strings. Convert them to floats for numerical operations
# later on
for (category, key) in df.columns:
if category in ["home", "away"]:
df[category, key] = df[category, key].astype(float)
# I would recommend using a MultiIndex for the columns:
# df[("match", "venue")]
# df[("home", "carries_crossed_gain_line")]
# df[("away", "conversion_goals")]
# but if you want to, you can flatten the column levels:
df.columns = df.columns.map("_".join)
# Now you can refer to columns like:
# df["match_venue"]
# df["home_carries_crossed_gain_line"]
# df["away_conversion_goals"]