我正在尝试根据名为 keywords
的字符串列表是否包含来自另一个 DataFrame 的 1 个或多个子字符串对其进行分类。
对子字符串进行加权,以便最后每个 keyword
的权重大约为 4 列。这些列将被称为 loan
、 mortgage
、 accounts
和 cards
。
我尝试使用 join()
、 concat()
和 merge()
来加入多个数据帧,并尝试使用 where()
、 isin()
和 contains()
。
我已经接近过几次以实现我想要的目标,但由于错误或可扩展性而受阻。我对 Python 和 Pandas 的经验有限,所以可能有一种我没有考虑过的完全不同的方法。
import pandas as pd
df = pd.read_csv('Inputs/keyword.csv', header=0)
df['loan'] = 0
df2 = pd.read_csv('Essentials/Groups/loans.csv', header=0)
#review the data in df
print(df.head())
output:
keywords search_volume loan
0 loans 132000 0
1 funding circle 81000 0
2 government 36000 0
3 short term loans 30000 0
4 company 27000 0
在上面的代码中,我正在加载我的关键字列表,包括相关的搜索量。它目前没有贷款列,所以我添加了一个,默认值设置为 0。
下面,我有另一个 DataFrame,其中包含一个术语列表和一个相关的权重。我随意选择了一个整数 5,我想将其添加到现有总数中。
#review the data in df2
print(df2.head())
output:
terms weight
0 loan 5
1 loans 5
2 personal 3
3 business 3
4 apr 4
我发现了一个问题,但不知道如何解决。
我的列表包括
loan
和 loans
。有这些副本对我来说很好。但是,第 3 行的值为“短期贷款”并标记为 False。由于术语
loan
和 loans
都出现在 short term loans
中,我原以为它会被标记为 True。我尝试反转 .isin()
语句,以便我在 df2['terms']
中搜索 df['keywords']
,但结果是一样的。#review the true/false for overlaps
print(df['keywords'].isin(df2['terms']).head())
output:
0 True
1 False
2 False
3 False
4 False
最后,一旦我们解决了这个 bool 问题,我不知道如何根据匹配对
df['loan']
中的总和变化进行矢量化。我试图避免 for 循环,因为我希望关键字列表包含大约 100,000 多行,并且每个类别 DataFrame 可能包含 1,000 个术语。所需的输出如下所示:
output:
keywords search_volume loan mortgage accounts cards
0 loans 132000 10 0 0 0
1 funding circle 81000 0 0 0 0
2 government 36000 0 0 0 0
3 short term loans 30000 10 0 0 0
4 company 27000 0 0 0 0
最佳答案
将 df1
视为:
keywords search_volume
0 loans 132000
1 funding circle 81000
2 government 36000
3 short term loans 30000
4 company 27000
您可以借助
series.str.extract()
和 df.assign()
,我们可以执行以下操作: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]
仅用于测试。然后使用
series.str.findall()
:s=df1.keywords.str.findall(pat)
df1=df1.assign(**{'term_match':s.apply(','.join),
'weight':s.apply(lambda x: sum([d.get(item,item) for item in x]))})
print(df1)
keywords search_volume loan term_match weight
0 loans 132000 0 loan 5
1 funding circle 81000 0 0
2 government 36000 0 0
3 short term loans 30000 0 term,loan 8
4 company 27000 0 0