【问题标题】:How to join two pandas Dataframe by rule contains values如何按规则加入两个熊猫数据框包含值
【发布时间】:2021-02-15 22:05:56
【问题描述】:

我有两个数据源:

df1 = pd.DataFrame({'a': [1, 2, 3, 4]})
df2 = pd.DataFrame({'b': [
    'Some text 11.',
    'Good 2 number',
    'Other 33 not valid',
    '4 is good too even with 7'
]})

df1 的样子

   a
0  1
1  2
2  3
3  4

df2 看起来像

                           b
0              Some text 11.
1              Good 2 number
2         Other 33 not valid
3  4 is good too even with 7

如果df1.a 列中的数字在df2.b 列中存在在任何位置,我的目标是合并它们,但只有确切的数字。 所以结果应该是:

a                         b
2              Good 2 number
4  4 is good too even with 7

我可以修改solution on string contains,但看起来很复杂。在真实数据中,两个来源都有超过 20k 条记录。

【问题讨论】:

    标签: python pandas dataframe merge


    【解决方案1】:

    您可以通过Series.str.extractall 获取所有数字到DataFrameSeries.unstack,转换为整数并通过DataFrame.isin 匹配,并通过DataFrame.any 测试每行是否至少有一个True:

    mask = (df2['b'].str.extractall('(\d+)')[0]
                    .astype(int)
                    .unstack()
                    .reindex(df2.index)
                    .isin(df1['a'])
                    .any(axis=1))
    df = df2[mask]
    print (df)
                               b
    1              Good 2 number
    3  4 is good too even with 7
    

    您可以将df1['a'] 的所有值通过| 连接到正则表达式or\b\b 用于单词边界并传递给Series.str.contains

    pat = '|'.join(r"\b{}\b".format(x) for x in df1['a'])
    df = df2[df2['b'].str.contains(pat)]
    print (df)
                               b
    1              Good 2 number
    3  4 is good too even with 7
    

    如果需要merge的解决方案:

    s = df2['b'].str.extractall('(\d+)')[0].astype(int).reset_index(level=1, drop=True)
    
    df = df1.merge(df2.join(s.rename('a')),on='a')
    print (df)
       a                          b
    0  2              Good 2 number
    1  4  4 is good too even with 7
        
    

    【讨论】:

    • 感谢您的回答。很抱歉错过了这两个来源在测试环境中拥有超过 20k 条记录并且在产品中可能更多的信息
    • @BrownBear - 我猜第二个应该更好
    • 第二个解决方案是我一直在寻找,再次感谢。也许可以放在答案的顶部)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-07
    • 2017-08-02
    • 2016-05-17
    • 1970-01-01
    相关资源
    最近更新 更多