python中包含两个df之间的字符串

2024-04-23 06:38:55 发布

您现在位置:Python中文网/ 问答频道 /正文

我有两个df和两个字符串列,如下所示:

Df1:原始df有2000行名称

Id    Name
1     Paper
2     Paper
3     Scissors
4     Mat
5     Cat
6     Cat

第二个测向:原始测向有1000多个项目名称

^{pr2}$

我需要列Name中的字符串,它们位于列项名称中

第一种方法:使用str.contains

我知道如何匹配字符串,如果它们是一列和要匹配的两个字符串,如下所示:

df[df['Name'].str.contains("paper|cat", na=False)]

但是当有两列字符串(name&Item_name)要匹配时该怎么办?在

第二种方法:Fuzzywuzzy

matched = []
for row in df1.index:
    name = df1.get_value(row,"Name")
    for columns in df2.index:
        item_name=df2.get_value(columns,"Item_Name")
        matched_token=fuzz.token_sort_ratio(name,item_name)
        if matched_token> 80:
            matched.append([name,item_name,matched_token])

问题是,它会很慢,而且我想要的输出是从fuzzyfuzzy得到的。输出如下:

Id Name     Item_ID
1  Paper     1,2,3
2  Paper     1,2,3
3  Scissors  NA 
4  Mat       NA 
5  Cat       4
6  Cat       4 

总结

  1. 怎么做结构包含如果它们是两个具有不同列名的df
  2. 如何转换df以获得上述预期输出

Tags: 方法字符串name名称tokeniddfitem
3条回答
df=pd.DataFrame({'ID':[1,2,3,4,5,6],'Name':['paper','paper','scissors','mat','cat','cat']})
df1=pd.DataFrame({'ID':[1,2,3,4],'Name':['paper bag','wallpaper','paper','cat cage']})


import numpy as np
def lookup_prod(ip):
    lst=[]
    for idx,row in df1.iterrows():
        if ip in row['Name']:
            lst.append(row['ID'])    
    if not lst:
        return np.NaN
    return lst

df['Item_ID'] = df['Name'].apply(lookup_prod)

输出:

^{pr2}$

您可以将^{}与自定义函数一起使用:

def matcher(x):
    res = df2.loc[df2['Item_Name'].str.contains(x, regex=False, case=False), 'Item_ID']
    return ','.join(res.astype(str))

df1['Item_ID'] = df1['Name'].apply(matcher)

print(df1)

   Id      Name Item_ID
0   1     Paper   1,2,3
1   2     Paper   1,2,3
2   3  Scissors        
3   4       Mat        
4   5       Cat       4
5   6       Cat       4

您可以通过以下方法提高效率:

  • 只处理df1['Name']中的唯一项:apply是一个行循环。在
  • 使用列表理解代替pd.Series.apply。两者都是Python级别的循环,但是列表理解通常比Pandasstr方法的性能要好。在

但上述方法并不能提高算法的复杂度。为了更好地改进数量级,您应该考虑基于trie的算法,例如利用Aho–Corasick algorithmthis answer。在

您可以在这里使用df.apply

def get_vals(df):
    return ','.join(map(str, df2.loc[df2['Item_Name'].str.contains(df['Name'], case=False),]['Item_ID'].tolist()))

df1['Item_ID'] = df1.apply(get_vals, axis=1)

输出:

^{pr2}$

相信这会给你想要的结果

相关问题 更多 >