如何合并字符串包含的熊猫?

Posted

技术标签:

【中文标题】如何合并字符串包含的熊猫?【英文标题】:How to merge pandas on string contains? 【发布时间】:2019-07-12 08:28:55 【问题描述】:

我有 2 个数据框,我想将它们合并到一个公共列上。但是,我想合并的列不是同一个字符串,而是一个字符串包含在另一个字符串中:

import pandas as pd
df1 = pd.DataFrame('column_a':['John','Michael','Dan','George', 'Adam'], 'column_common':['code','other','ome','no match','word'])

df2 = pd.DataFrame('column_b':['Smith','Cohen','Moore','K', 'Faber'], 'column_common':['some string','other string','some code','this code','word'])

我希望d1.merge(d2, ...) 得到的结果如下:

column_a  |  column_b
----------------------
John      |  Moore    <- merged on 'code' contained in 'some code' 
Michael   |  Cohen    <- merged on 'other' contained in 'other string'  
Dan       |  Smith    <- merged on 'ome' contained in 'some string'  
George    |  n/a
Adam      |  Faber    <- merged on 'word' contained in 'word'  

【问题讨论】:

为什么'John' 不匹配K 因为'this code' @ALollz 那是因为“一些代码”是第一位的 【参考方案1】:

新答案

这是一种基于 pandas/numpy 的方法。

rhs = (df1.column_common
          .apply(lambda x: df2[df2.column_common.str.find(x).ge(0)]['column_b'])
          .bfill(axis=1)
          .iloc[:, 0])

(pd.concat([df1.column_a, rhs], axis=1, ignore_index=True)
 .rename(columns=0: 'column_a', 1: 'column_b'))

  column_a column_b
0     John    Moore
1  Michael    Cohen
2      Dan    Smith
3   George      NaN
4     Adam    Faber

旧答案

这是左连接行为的解决方案,因为它不会保留与任何 column_b 值不匹配的 column_a 值。这比上面的 numpy/pandas 解决方案要慢,因为它使用两个嵌套的 iterrows 循环来构建 python 列表。

tups = [(a1, a2) for i, (a1, b1) in df1.iterrows() 
                 for j, (a2, b2) in df2.iterrows()
        if b1 in b2]

(pd.DataFrame(tups, columns=['column_a', 'column_b'])
   .drop_duplicates('column_a')
   .reset_index(drop=True))

  column_a column_b
0     John    Moore
1  Michael    Cohen
2      Dan    Smith
3     Adam    Faber

【讨论】:

嗯。但它是纯 python 解决方案。可以用pandasnumpy 完成吗?例如。 applymapjoinmerge 等的组合 @Peter Leimbigler,嗯,这是一种方法。然而,我正在寻找与 Alex Yu 的建议类似的东西 这当然可以改进!这是第一个想到的本能解决方案。它是否在您的数据量可接受的时间内运行?如果是这样,为什么还要进行优化? ;) 明白了。我的旧答案在我有限的测试中表现很差。我已经编辑了一个更新的、稍微快一点的解决方案——尽管它的可读性较差。 啊哈!这正是我自己试图找到的!谢谢!【参考方案2】:

我的解决方案涉及将函数应用于公共列。我无法想象当 df2 很大时它会保持得很好,但也许有比我更有知识的人提出改进建议。

def strmerge(strcolumn):
    for i in df2['column_common']:
        if strcolumn in i:
            return df2[df2['column_common'] == i]['column_b'].values[0]

df1['column_b'] = df1['column_common'].apply(strmerge)

df1
    column_a    column_common   column_b
0   John        code            Moore
1   Michael     other           Cohen
2   Dan         ome             Smith
3   George      no match        None
4   Adam        word            Faber

【讨论】:

以上是关于如何合并字符串包含的熊猫?的主要内容,如果未能解决你的问题,请参考以下文章

当两个数据框都包含重复键时,如何将两个熊猫数据框与左连接合并?

如何在熊猫数据框单元格中提取部分字符串并在其中创建一个包含该字符串的新列

如何从包含特定列中特定字符串的熊猫数据框中删除行? [复制]

如何过滤熊猫系列索引中的字符串

如何按字符串过滤熊猫数据框?

如何比较具有字符串和整数的列?蟒蛇熊猫