【问题标题】:How can i edit this dataframe to merge two columns dictionaries lists?如何编辑此数据框以合并两列字典列表?
【发布时间】:2020-06-12 08:54:19
【问题描述】:

我有一个这样的数据框。

ID  Name id2                            name2                  name3
101  A    [{'a': '1'}, {'b': '2'}]  [{'e': '4'}, {'f': '5'}]  [{'x': '4'}, {'y': '5'}]
103  B    [{'c': '3'},{'d': '6'}]   [{'g': '7'},{'h': '8'}]   [{'t': '4'}, {'o': '5'}]

我想要这样的输出df。

ID   Name id2                                                                name2
101  A    [{'a': '1','e': '4','x': '4'}, {'b': '2', 'f': '5','y': '5'}}]    [{'e': '4'}, {'f': '5'}]
103  B    [{'c': '3', 'g': '7','t': '4'},{'d': '6', 'h': '8','o': '5'}]    [{'e': '4'}, {'f': '5'}]

列名 3 将与我刚刚从上面的示例中删除的 Op 中的一样。问题是即使添加了更多列,它的字典也会在 id2 列中更新。 谢谢:)

【问题讨论】:

  • if there is any another column present next after it你能解释一下吗?
  • @yatu 你可以认为只有 4 列存在。
  • 谢谢@ChrisA 今天你救了我。 :) 如果你有时间可以详细解释一下代码吗?
  • 嘿@R.singh 我实际上添加了另一个官方解决方案,它比使用dict.update更好一点

标签: python pandas list pandas-groupby


【解决方案1】:

您可以尝试在列表理解中使用collections.ChainMap

来自文档...

ChainMap 将多个 dicts 或其他映射组合在一起以创建单个可更新的视图...

所以首先我们将zip 列放在一起,然后嵌套zip 以在单个列表中“并排”从每一列中获取dicts。这个列表被传递给ChainMap,它将它们连接成一个dict

示例

from collections import ChainMap

# Setup    
df = pd.DataFrame({'ID': [101, 103], 'Name': ['A', 'B'], 'id2': [[{'a': '1'}, {'b': '2'}], [{'c': '3'}, {'d': '6'}]], 'name2': [[{'e': '4'}, {'f': '5'}], [{'g': '7'}, {'h': '8'}]]})

df['id2'] = [[dict(ChainMap(*x)) for x in zip(i, n)]
             for i, n in zip(df['id2'], df['name2'])]

[出]

    ID Name                                           id2                     name2
0  101    A  [{'e': '4', 'a': '1'}, {'b': '2', 'f': '5'}]  [{'e': '4'}, {'f': '5'}]
1  103    B  [{'c': '3', 'g': '7'}, {'d': '6', 'h': '8'}]  [{'g': '7'}, {'h': '8'}]

更新

一个更具扩展性的解决方案,如果您有多个要组合的列,则首先使用DataFrame.filter 来提取所有需要组合的列:

df = pd.DataFrame({'ID': [101, 103], 'Name': ['A', 'B'], 'id2': [[{'a': '1'}, {'b': '2'}], [{'c': '3'}, {'d': '6'}]], 'name2': [[{'e': '4'}, {'f': '5'}], [{'g': '7'}, {'h': '8'}]], 'name3': [[{'x': '4'}, {'y': '5'}], [{'t': '4'}, {'o': '5'}]]})

df['id2'] = [[dict(ChainMap(*y)) for y in zip(*x)]
             for x in zip(*df.filter(regex='id2|name').apply(tuple))]

[出]

    ID Name                                                               id2                     name2                     name3
0  101    A  [{'e': '4', 'x': '4', 'a': '1'}, {'b': '2', 'f': '5', 'y': '5'}]  [{'e': '4'}, {'f': '5'}]  [{'x': '4'}, {'y': '5'}]
1  103    B  [{'c': '3', 't': '4', 'g': '7'}, {'o': '5', 'd': '6', 'h': '8'}]  [{'g': '7'}, {'h': '8'}]  [{'t': '4'}, {'o': '5'}]

这基本上和上面做的一样,只是我们过滤到“id”或“name”列,并将它们全部组合起来。

【讨论】:

  • 谢谢@Chris,如果你有时间可以解释一下这段代码吗?
  • 我已经用你试过这个方法 [[(x.update(y)) for x, y in zip(i, n)] for i, n in zip(df2['id2'] , df2['name2'])] 这就像一个魅力。再次感谢克里斯
  • 我已经更新了这个问题,以便将来进行一些修改,您能否提出建议?
  • @R.singh 更新的解决方案,如果您现在有多个“名称”列,应该更具可扩展性
【解决方案2】:

考虑到你的数据框的名称是 df,试试这个:

i=0
for i in range(0,df.shape[0]):
    df.id2[i][0].update(df.name2[i][0])
    df.id2[i][1].update(df.name2[i][1])

【讨论】:

    猜你喜欢
    • 2016-01-02
    • 1970-01-01
    • 1970-01-01
    • 2022-11-28
    • 2018-05-20
    • 2019-09-19
    • 2013-11-02
    相关资源
    最近更新 更多