Python 匹配多个数据帧之间的子字符串,并在单独的列中求和加权值
我试图根据是否包含来自另一个数据帧的1个子字符串或多个子字符串,对名为Python 匹配多个数据帧之间的子字符串,并在单独的列中求和加权值,python,python-3.x,string,pandas,Python,Python 3.x,String,Pandas,我试图根据是否包含来自另一个数据帧的1个子字符串或多个子字符串,对名为关键字的字符串列表进行分类 对子字符串进行加权,使每个关键字的末尾在大约4列中具有权重。这些列将被称为贷款,抵押,账户,以及卡 我尝试使用join()、concat()和merge()来连接多个数据帧,还尝试使用where()、isin()和contains() 为了达到我想要的目标,我已经接近了好几次,但由于错误或可伸缩性而受阻。我对Python和Pandas的经验有限,因此可能有一种完全不同的方法,我没有考虑过 将熊猫作为
关键字的字符串列表进行分类
对子字符串进行加权,使每个关键字
的末尾在大约4列中具有权重。这些列将被称为贷款
,抵押
,账户
,以及卡
我尝试使用join()
、concat()
和merge()
来连接多个数据帧,还尝试使用where()
、isin()
和contains()
为了达到我想要的目标,我已经接近了好几次,但由于错误或可伸缩性而受阻。我对Python和Pandas的经验有限,因此可能有一种完全不同的方法,我没有考虑过
将熊猫作为pd导入
df=pd.read\u csv('Inputs/keyword.csv',header=0)
df['loan']=0
df2=pd.read\u csv('Essentials/Groups/loans.csv',header=0)
#查看df中的数据
打印(df.head())
输出:
关键词搜索量贷款
0贷款132000 0
1资助圈81000
2政府36000
3短期贷款300000
4公司27000
在上面的代码中,我正在加载我的关键字列表,包括一个关联的搜索卷。它目前没有loan列,所以我添加了一个默认值设置为0的列
下面,我有另一个数据帧,它包括一个术语列表和相关的权重。我任意选择了一个5的整数,我想把它加到现有的总数中
#查看df2中的数据
打印(df2.head())
输出:
术语权重
0贷款5
1贷款5
2个人3
3业务3
4月4日
我发现了一个问题,但不知道如何解决
我的列表包括贷款
和贷款
。把这些复制品放在我的头上对我来说很好。但是,第3行的值为“短期贷款”,并标记为False
由于贷款
和贷款
这两个术语都出现在短期贷款
中,因此我希望它被标记为True。我尝试反转.isin()
语句,以便在df['keywords']
中搜索df2['terms']
,但结果是一样的
#检查真/假重叠
打印(df['keywords'].isin(df2['terms']).head())
输出:
0对
1错误
2错误
3错误
4错误
最后,一旦我们解决了这个布尔问题,我就不知道如何根据匹配来向量化df['loan']
中的总和变化。我试图避免for循环,因为我希望关键字列表包含100000多行,每个类别数据框可能包含1000个术语
所需的输出如下所示:
输出:
关键词搜索\批量贷款抵押贷款账户卡
0贷款132000 10000
1资助圈81000
2政府36000
3短期贷款30000 100
4公司27000
将df1
视为:
keywords search_volume
0 loans 132000
1 funding circle 81000
2 government 36000
3 short term loans 30000
4 company 27000
您可以借助我们的帮助,我们可以采取以下措施:
d=df2.set_index('terms')['weight']
pat=r'({})'.format('|'.join(df2.terms))
#'(loan|loans|personal|business|apr)'
df1=df1.assign(**{'term_match':df1.keywords.str.extract(pat,expand=False),
'weight':df1.keywords.str.extract(pat,expand=False).map(d)})
print(df1)
输出
keywords search_volume term_match weight
0 loans 132000 loan 5.0
1 funding circle 81000 NaN NaN
2 government 36000 NaN NaN
3 short term loans 30000 loan 5.0
4 company 27000 NaN NaN
编辑
为了找到所有匹配的字符串,让我们将df2
更新为:df2.loc[5]=['term',3]
仅用于测试
然后使用:
下面是一种查找匹配数量的方法。这可能会在正确的方向上帮助你
首先使用以下方法分解字符串以分隔行:
然后我们使用difflib
模块获得最接近的匹配,例如loan
与loans
:
import difflib
df['loan'] = df.set_index('keywords').index.map(lambda x: difflib.get_close_matches(x, df2.set_index('terms').index))
keywords search_volume loan
0 loans 132000 [loans, loan]
1 funding 81000 []
1 circle 81000 []
2 government 36000 []
3 short 30000 []
3 term 30000 []
3 loans 30000 [loans, loan]
4 company 27000 []
然后我们对索引进行分组,以获取原始数据帧,并计算匹配的长度:
df = df.groupby(df.index).agg({'keywords':' '.join,
'search_volume':'last',
'loan':'last'})
df['count'] = df['loan'].str.len()
keywords search_volume loan count
0 loans 132000 [loans, loan] 2
1 funding circle 81000 [] 0
2 government 36000 [] 0
3 short term loans 30000 [loans, loan] 2
4 company 27000 [] 0
剩下的唯一一件事就是将计数与权重相乘,你得到了你想要的。loan 10在你的预期输出中是什么样子的?@Erfan loan和loans都可以放在“loans”中,所以它是5+5。你是在寻找df1.keywords.str.contains(r'\b{}\b'.format('|'.join(df2.terms))
[真,假,假,真,假]
?根据您提供的输入,预期的输出是如何的?@anky_91这看起来是正确的输出,但我不完全确定您编写的代码中发生了什么。我的想法是,我有一个大约100,00个关键字和大约1000个术语的列表,然后将用于对这些k进行分类eywords。例如,如果关键字是一种贷款类型,它将包括与贷款相关的术语。下面是一个较长的关键字示例,可以更清楚地说明我为什么对每个术语进行加权:如何获得信用不良的初创企业贷款
诸如“如何”等词表示问题,而“信用不良”和“贷款”表示贷款。@RowanCollins收到了,但有一个问题,您打算如何在这里创建新列,一个匹配术语的列和填充值是否足够?这看起来非常好,我在匹配df2
术语时将weight
列修改为loan
。这对我们很有用当前的最高值,而不是总额。例如,如果存在[[loans,5],[term,3]]
,则短语“短期贷款”结果应该是8。使用上述方法,我几乎达到了我需要的程度-但这不是所有匹配项的总和-只是单个匹配项的权重。@RowanCollins您可以添加一列df1['sum_weights']=df1.groupby('term_match')。weight.transfo
df = explode_str(df, 'keywords', ' ')
keywords search_volume loan
0 loans 132000 0
1 funding 81000 0
1 circle 81000 0
2 government 36000 0
3 short 30000 0
3 term 30000 0
3 loans 30000 0
4 company 27000 0
import difflib
df['loan'] = df.set_index('keywords').index.map(lambda x: difflib.get_close_matches(x, df2.set_index('terms').index))
keywords search_volume loan
0 loans 132000 [loans, loan]
1 funding 81000 []
1 circle 81000 []
2 government 36000 []
3 short 30000 []
3 term 30000 []
3 loans 30000 [loans, loan]
4 company 27000 []
df = df.groupby(df.index).agg({'keywords':' '.join,
'search_volume':'last',
'loan':'last'})
df['count'] = df['loan'].str.len()
keywords search_volume loan count
0 loans 132000 [loans, loan] 2
1 funding circle 81000 [] 0
2 government 36000 [] 0
3 short term loans 30000 [loans, loan] 2
4 company 27000 [] 0