我有一些数据(如下所示),这是一个包含嵌套词典列表的词典. 我想把整个词典变成一行.一排很宽的一排. 目前我可以得到我想要的结果.它相当长,而且不是很优雅. 我希望更好地编写更简洁的代码,并希望编写更高效的代码.

出于上下文考虑,我是为了一个大学项目而这样做的.我们没有在代码优雅或优化方面得到标记.这更多的是为了我自己的利益.

由于对Python还很陌生,我不太擅长使用某种词典的嵌套词典和嵌套词典列表. 任何帮助都将不胜感激!

Data dictionary

{'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'}]}

Desired outcome a wide row like: enter image description here

What I've tried 我创建了一个函数,可以用它来调用每个嵌套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']))

然后我

  1. 将帧串成一行.
  2. 将"主页"前置添加到所有列.
  3. 对客场球队重复步骤一和二,并在列中添加前置"away"
  4. 将两个结果连接到一个非常非常宽的行中.
  5. 将比赛详细信息Meta数据添加到行中,使其非常、非常、非常宽.
  6. 对每套匹配数据重复此操作.

这很耗时.有没有一种方法可以以更有效或更Python 的方式做到这一点? 我的最终目标是收集主队和客场球队的比赛数据(因此数据框宽度增加一倍),并每场比赛进行一行.

Extra data for reference 结果:我只对"比赛"]、"主场"]和"客场"]词典感兴趣. 在主场和客场词典中,我试图提取的"team_stats"部分. 此数据来自API.我首先将响应转换为json格式. 每场比赛我都会处理一组这样的数据.目标是参加大约250多场比赛.

data

推荐答案

试试这个:

# Assuming `rugby_data`` is the deserialized JSON object from your sample input
df = (
    pd.DataFrame(
        # The idea is to convert it 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"]

Python相关问答推荐

一切似乎都可以自己工作,但当我把它放在一起时,它会抛出RegexMatch错误

为什么Pydantic在我申报邮箱时说邮箱丢失

每个组每第n行就有Pandas

使用Curses for Python保存和恢复终端窗口内容

Docker-compose:为不同项目创建相同的容器

GEKKO:已知延迟的延迟系统的参数估计

如何在不使用字符串的情况下将namedtuple属性传递给方法?

telegram 机器人API setMyName不起作用

Polars -转换为PL后无法计算熵.列表

inspect_asm不给出输出

阅读Polars Python中管道的函数定义

如何防止Plotly在输出到PDF时减少行中的点数?

Odoo -无法比较使用@api.depends设置计算字段的日期

Python库:可选地支持numpy类型,而不依赖于numpy

在Mac上安装ipython

ODE集成中如何终止solve_ivp的无限运行

Python—从np.array中 Select 复杂的列子集

名为__main__. py的Python模块在导入时不运行'

在pandas数据框中计算相对体积比指标,并添加指标值作为新列

将标签移动到matplotlib饼图中楔形块的开始处