【问题标题】:Reassign pandas series values using nested defaultdict使用嵌套的 defaultdict 重新分配 pandas 系列值
【发布时间】:2020-04-01 13:03:05
【问题描述】:

我正在处理一个 NFL 数据集,并希望为 df 中的每场比赛进行以下映射:

  • 我正在尝试在列 (DistToRusher) 中填充每个球员与该比赛的冲球手的距离。
  • DistToRusher 列当前填充了玩家 ID。
  • 我正在尝试将这些玩家 id 映射到内部字典键中的那些,并用内部字典值替换它们。
  • 我有一个 defaultdict-of-dictionaries dist_dict,如下所示:
    dist_dict = {play_id1: {player_id1: distance, player_id2: distance ...}, 
                 play_id2: {player_id1: distance, player_id2: distance ...}...}

这是我的代码:

def populate_DistToRusher_column(df):
    for play_id, players_dict in dist_dict.items():
        df[df.PlayId == play_id].replace({'DistToRusher': players_dict}, inplace=True)
    return df

此代码运行缓慢(20-30 秒),并且不会更改 DistToRusher 列;当我检查 df 时,DistToRusher 仍然包含玩家 ID 号码而不是距离。

这是实际数据的玩具版本:

from collections import defaultdict 
import pandas as pd
df = pd.DataFrame.from_dict({'PlayId': {
  0: 20170907000118, 1: 20170907000118, 2: 20170907000118,
  22: 20170907000139, 23: 20170907000139, 24: 20170907000139},
 'NflId': {0: 496723, 1: 2495116, 2: 2495493,
  22: 496723, 23: 2495116, 24: 2495493},
 'NflIdRusher': {0: 2543773, 1: 2543773, 2: 2543773,
  22: 2543773, 23: 2543773, 24: 2543773},
 'DistToRusher': {0: 496723, 1: 2495116, 2: 2495493,
  22: 496723, 23: 2495116, 24: 2495493}})

dist_dict = {20170907000118: defaultdict(float,
             {496723: 6.480871854928166,
              2495116: 4.593310353111358,
              2495493: 5.44898155621764}),
 20170907000139: defaultdict(float,
             {496723: 8.583355987025117,
              2495116: 5.821151088917024,
              2495493: 6.658686056573021})}

【问题讨论】:

  • 查看pandas.pydata.org/pandas-docs/stable/reference/api/…,您应该能够通过地图和字典完成此操作。
  • 感谢@oppressionslayer,但即使我映射它,它仍然返回相同的结果。
  • 如果您可以发布部分数据:df[0:10].to_dict() 和您使用的内部键/值,我可以进一步查看
  • @oppressionslayer 感谢您的帮助!我用实际数据的小型化版本更新了问题。
  • 如果我的回答正确,请告诉我。我想这就是你要找的,如果不是让我知道我需要改变什么。谢谢!

标签: python pandas mapping transform defaultdict


【解决方案1】:

我认为这是对的,IIUC:

temp = pd.DataFrame(dist_dict)
df['DistToRusher2'] = df.apply(lambda x: temp[x.PlayId][x.NflId], axis=1)

or

df['DistToRusher2'] = df.apply(lambda x: dist_dict[x.PlayId][x.NflId], axis=1)

输出:

            PlayId    NflId  NflIdRusher  DistToRusher  DistToRusher2
0   20170907000118   496723      2543773        496723       6.480872
1   20170907000118  2495116      2543773       2495116       4.593310
2   20170907000118  2495493      2543773       2495493       5.448982
22  20170907000139   496723      2543773        496723       8.583356
23  20170907000139  2495116      2543773       2495116       5.821151
24  20170907000139  2495493      2543773       2495493       6.658686

【讨论】:

    【解决方案2】:

    感谢@oppressionslayer!这就像一个魅力:

    df['DistToRusher2'] = df.apply(lambda x: dist_dict[x.PlayId][x.NflId], axis=1)
    

    【讨论】:

      猜你喜欢
      • 2013-10-11
      • 2020-05-02
      • 2016-04-07
      • 2019-04-16
      • 2016-11-28
      • 2015-04-22
      相关资源
      最近更新 更多