【问题标题】:How can I combine two dataframes based on a column of lists in Pandas如何根据 Pandas 中的一列列表组合两个数据框
【发布时间】:2021-04-03 06:20:27
【问题描述】:
import pandas as pd

可重复设置

我有两个数据框:

df=\
pd.DataFrame.from_dict({'A':['xy','yx','zy','zz'],
                        'B':[[1, 3],[4, 3, 5],[3],[2, 6]]})

df2=\
pd.DataFrame.from_dict({'B':[1,3,4,5,6],
                        'C':['pq','rs','pr','qs','sp']})

df 看起来像:

    A          B
0  xy     [1, 3]
1  yx  [4, 3, 5]
2  zy        [3]
3  zz     [2, 6]

df2 看起来像:

   B   C
0  1  pq
1  3  rs
2  4  pr
3  5  qs
4  6  sp

目标

我想将这两者结合起来形成res

res=\
pd.DataFrame.from_dict({'A':['xy','yx','zy','zz'],
                        'C':['pq','pr','rs','sp']})

    A   C
0  xy  pq
1  yx  pr
2  zy  rs
3  zz  sp

df 中带有xy 的行具有 lsit [1,3]。在df2 的列B 中有一行值为1C 列在该行中具有值 pq,因此我将 xypq 组合在一起。接下来的两行也一样。最后一行:df2 中的B 列中没有 2 的值,所以我选择值 6df 中的最后一行有列表[2,6])。


问题

如何在不遍历数据框的情况下实现这一点?


Spanish SO 中的一个非常相似的帖子,启发了这篇帖子。

【问题讨论】:

    标签: python pandas dataframe merge


    【解决方案1】:

    您可以将explode“B”分成单独的行,然后在“B”上合并并删除重复项。

    非常感谢 cmets 中的 Asish M. 指出了排序的潜在错误。

    (df.explode('B')
       .merge(df2, on='B', how='left')
       .dropna(subset=['C'])
       .drop_duplicates('A'))
    
        A  B   C
    0  xy  1  pq
    2  yx  4  pr
    5  zy  3  rs
    7  zz  6  sp
    

    理想情况下,以下应该有效:

    df.explode('B').merge(df2).drop_duplicates('A')
    

    但是,pandas(在撰写本文时,版本 1.2dev)不保留合并时左键的顺序,这是一个错误,请参阅 GH18776

    与此同时,我们可以使用左合并的解决方法,如上所示。

    【讨论】:

    • 要么它是一个熊猫错误 - 但内部连接似乎不尊重顺序(它似乎是根据左键的“插入”顺序对其进行排序) - 你可以看到yx 的值应该是 pr 但这会返回 rs
    • 左连接 dropna 后跟 drop_duplicates 修复了这个问题
    • 这里已经有一个错误:github.com/pandas-dev/pandas/issues/18776
    • @AsishM。谢谢,发现了!
    猜你喜欢
    • 1970-01-01
    • 2018-11-24
    • 2022-08-11
    • 2016-10-08
    • 1970-01-01
    • 1970-01-01
    • 2017-09-03
    相关资源
    最近更新 更多