【问题标题】:Applying a key value dictionary pair to multiple column in a dataframe将键值字典对应用于数据框中的多列
【发布时间】:2021-04-22 15:57:32
【问题描述】:

我需要将更改应用到 2 列中的当前数据帧,其中一个列的字典键和来自 dict 的每个值的值到另一列。例如,我无法找到任何方法来做到这一点。

dict is - test = {'a':32, 'b':21, 'c':92}

当前数据框看起来像

date         env   result         cost

2021-03-01   dev      gcp.dev.a         30
2021-03-01   prd      gcp.prd.d         35
2021-03-01   dev      gcp.dev.j         98
2021-03-01   sandbox  gcp.sandbox.b     94

在结果和成本列数据框的字典中添加更改后,应如下所示 -

date         env        result          cost

2021-03-01   dev      gcp.dev.a           30
2021-03-01   prd      gcp.prd.d           35
2021-03-01   dev      gcp.dev.j           98
2021-03-01   sandbox  gcp.sandbox.b       94
2021-03-01   dev      gcp.dev.a           32 
2021-03-01   prd      gcp.prd.b           21  
2021-03-01   prd     gcp.prd.c          92

这里 gcp 是一个固定值,正在添加,dev 和 prd 来自 env 列。

您注意到最后 3 行是通过测试字典键值添加的,每个键值都添加到结果和成本中。即应在每个键值对的两列中添加相关行

【问题讨论】:

    标签: python python-3.x pandas dataframe


    【解决方案1】:

    您也可以使用pd.DateFrame.from_dict() 方法、append() 方法和ffill() 方法来做到这一点:

    test = {'a':32, 'b':21, 'c':92}
    
    newdf=pd.DataFrame(test.values(),index=test.keys(),columns=['cost']).reset_index()
        #OR(use any one of them to create dataframe named newdf)
    newdf=pd.DataFrame.from_dict(test,orient='index',columns=['cost']).reset_index().rename(columns={'index':'result'})
    

    最后:

    newdf=df.append(newdf,ignore_index=True).ffill()
    

    现在,如果您打印 newdf,您将获得所需的输出:

        date         result     cost
    0   2021-03-01      a       30
    1   2021-03-01      d       35
    2   2021-03-01      j       98
    3   2021-03-01      b       94
    4   2021-03-01      a       32
    5   2021-03-01      b       21
    6   2021-03-01      c       92
    

    【讨论】:

    • 我有一个连锁的但同样的方法真的df.append(pd.DataFrame.from_dict(test, orient='index', columns=['cost']).rename_axis(['result'], axis=0).reset_index()).ffill()
    • 好的先生...我删除了...我发现它更有效所以我添加了它...对不起:)
    • 是否可以在此命令中进行一些更改以适应结果 acc['result'] = acc.apply(lambda x: [f'{squ}' for squ, cost in test.items()], axis=1) 使用 lambda ?
    • 如果你想要'result'列的单个值是str类型,那么你可以做acc['result']=str([f'{squ}' for squ, cost in test.items()]) 如果你想要'result'列的单个值是list 类型,然后使用 acc['result']=acc['result'].apply(lambda x: [f'{squ}' for squ, cost in test.items()])
    • 我想要从测试字典中添加成本和结果列的相同输出,但是如果您现在看到我的问题,我需要添加其他变量,这些变量正在使用字典键添加到结果列中。所以这就是问题所在。
    【解决方案2】:

    由 cosntructor 创建新的 DataFrame 并将其添加到原始的 concat,最后向前填充 date 值:

    test  = {'a':32, 'b':21, 'c':92}
    
    df1 = pd.DataFrame(list(test.items()), columns=['result','cost'])
    
    df = pd.concat([df, df1], ignore_index=True)
    df['date'] = df['date'].ffill()
    print (df)
             date result  cost
    0  2021-03-01      a    30
    1  2021-03-01      d    35
    2  2021-03-01      j    98
    3  2021-03-01      b    94
    4  2021-03-01      a    32
    5  2021-03-01      b    21
    6  2021-03-01      c    92
    

    循环解决方案是可能的,但速度很慢,所以不推荐:

    for k, v in test.items():
        df.loc[len(df), ['result','cost']] = (k, v)
    
    df['date'] = df['date'].ffill()
    

    【讨论】:

      【解决方案3】:

      resultcost 设置为索引:

      temp = df.set_index(['result', 'cost']) 
      

      从字典构建MultiIndex

      test_index = pd.MultiIndex.from_tuples(test.items(), names = ['result', 'cost'])
      

      使用temp 的索引和test_index 的联合重新索引temp

      (temp
       .reindex(temp.index.union(test_index, sort = False))
       .ffill() 
       .reset_index()
       .reindex(columns = df.columns)
       )
       
               date result  cost
      0  2021-03-01      a    30
      1  2021-03-01      d    35
      2  2021-03-01      j    98
      3  2021-03-01      b    94
      4  2021-03-01      a    32
      5  2021-03-01      b    21
      6  2021-03-01      c    92
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-11-28
        • 2018-12-13
        • 2021-08-24
        • 2021-05-14
        • 2021-10-13
        • 2018-05-03
        • 2020-11-06
        • 1970-01-01
        相关资源
        最近更新 更多