假设我有两个数据帧df1和df2。 如果df1的特定列的值包含df2的特定列中的字符串,则我想将df2的一些列附加到df1,否则为NaN。
一个小例子:
import pandas as pd
df1 = pd.DataFrame({'col': ['abc', 'def', 'abg', 'xyz']})
df2 = pd.DataFrame({'col1': ['ab', 'ef'], 'col2': ['match1', 'match2'], 'col3': [1, 2]})
df1:
col
0 abc
1 def
2 abg
3 xyz
df2:
col1 col2 col3
0 ab match1 1
1 ef match2 2
我想:
col col2_match col3_match
0 abc match1 1
1 def match2 2
2 abg match1 1
3 xyz NaN NaN
我设法以肮脏和低效的方式做到这一点,但在我的情况下,df1包含100K行,它需要永远......
提前致谢!
修改
有点脏,但相对较快地完成了工作(我仍然认为存在最聪明的方式......):
import pandas as pd
import numpy as np
df1 = pd.DataFrame({'col': ['abc', 'def', 'abg']})
df2 = pd.DataFrame({'col1': ['ab', 'ef'],
'col2': ['match1', 'match2'],
'col3': [1, 2]})
def return_nan(tup):
return(np.nan if len(tup[0]) == 0 else tup[0][0])
def get_indexes_match(l1, l2):
return([return_nan(np.where([x in e for x in l2])) for e in l1])
def merge(df1, df2, left_on, right_on):
df1.loc[:, 'idx'] = get_indexes_match(df1[left_on].values,
df2[right_on].values)
df2.loc[:, 'idx'] = np.arange(len(df2))
return(pd.merge(df1, df2, how='left', on='idx'))
merge(df1, df2, left_on='col', right_on='col1')
答案 0 :(得分:0)
你可以像这样使用python difflib模块进行模糊匹配
import difflib
difflib.get_close_matches
df1.col = df1.col.map(lambda x: difflib.get_close_matches(x, df2.col1)[0])
所以现在你的df1是
col
0 ab
1 ef
2 ab
如果您希望保持df1不变,可以将其命名为df3。
现在你可以合并
了merged = df1.merge(df2, left_on = 'col', right_on = 'col1', how = 'outer').drop('col1', axis = 1)
合并的数据框看起来像
col col2 col3
0 ab match1 1
1 ab match1 1
2 ef match2 2
编辑: 如果不匹配给出的新示例,则只需要在lambda中放置条件
df1.col = df1.col.map(lambda x: difflib.get_close_matches(x, df2.col1)[0] if difflib.get_close_matches(x, df2.col1) else x)
现在合并后你得到了
col col2 col3
0 ab match1 1
1 ab match1 1
2 ef match2 2
3 xyz NaN NaN