这是我的问题(我正在使用python):
我有一个带有列的数据框:Index(['job_title', 'company', 'job_label', 'description'], dtype='object')
我有一个包含300个技能的单词列表:
keywords = ["C++","Data Analytics","python","R", ............ "Django"]
我需要将这些关键字与每个职位描述相匹配,并获得一个新的数据框,说明职位描述[0] ...职位描述[1],职位描述[2]和以此类推。
我的新数据框将是:
列:['job_title','company','description',“ C ++”,“ Data Analytics”, .......“ Django”]
在职位描述中,如果关键字的每一列均匹配(不匹配),则为true或false。
可能还有另一种构造数据框的方法(我在听建议)。
希望我对我的问题很清楚。我尝试使用正则表达式,但无法遍历每一行,我尝试使用“ fnmatch”库进行循环,但无法使其正常工作。迄今为止最好的方法是:
df["microservice"]= df.description.str.contains("microservice")
df["cloud-based architecture"] = df.description.str.contains("cloud-based architecture")
df["service oriented architecture"] = df.description.str.contains("service oriented architecture")
但是,首先,我无法使它遍历描述列的每一行,因此我必须为每个单词输入300倍的代码(这没有意义)。其次,通过这种方式,我很少遇到“ R”之类的词,因为它在每个描述中都能找到字母R,因此每个词都适用。
答案 0 :(得分:2)
遍历关键字列表并从描述中提取每一列。
for name in keywords:
df[name] = df['description'].apply(lambda x: True if name in x else False)
编辑:
这不能解决R的问题。为此,您可以添加一个空格以确保它是隔离的,因此代码应为:
for name in keywords:
df[name] = df['description'].apply(lambda x: True if ' '+str(name)+' ' in x else False)
但这确实很丑,而且不容乐观。正则表达式应该可以解决问题,但我必须回顾一下:找到了! [] * + [str(name)] + [。?!]更好! (并且更合适)
答案 1 :(得分:1)
一种方法是构建一个正则表达式字符串以标识字符串中的任何关键字...此示例不区分大小写,并且会找到任何子字符串匹配项-不仅是整个单词...
import pandas as pd
import re
keywords = ['python', 'C++', 'admin', 'Developer']
rx = '(?i)(?P<keywords>{})'.format('|'.join(re.escape(kw) for kw in keywords))
然后使用DF样本:
df = pd.DataFrame({
'job_description': ['C++ developer', 'traffic warden', 'Python developer', 'linux admin', 'cat herder']
})
您可以找到相关列的所有关键字...
matches = df['job_description'].str.extractall(rx)
哪个给:
keyword
match
0 0 C++
1 developer
2 0 Python
1 developer
3 0 admin
然后,您要使用以下方法获取“假人”列表并取最大值(因此,总会在找到单词的地方得到1):
dummies = pd.get_dummies(matches).max(level=0)
哪个给:
keyword_C++ keyword_Python keyword_admin keyword_developer
0 1 0 0 1
2 0 1 0 1
3 0 0 1 0
然后您将其加入原来的DF:
result = df.join(dummies, how='left')
结果是:
job_description keyword_C++ keyword_Python keyword_admin keyword_developer
0 C++ developer 1.0 0.0 0.0 1.0
1 traffic warden NaN NaN NaN NaN
2 Python developer 0.0 1.0 0.0 1.0
3 linux admin 0.0 0.0 1.0 0.0
4 cat herder NaN NaN NaN NaN
答案 2 :(得分:0)
Index(['job_title', 'company', 'job_label', 'description'],
dtype='object')
一个幼稚的实现可能看起来像这样:
for skill in keywords:
for frame in jobs:
if skill in frame["description"]: # or more exact matching, but this is what's in the question
# exists
但是您需要对要使用的输出结构进行更多工作。仅具有300列的输出数组,其中大多数仅包含False
并不是一个好计划。我从来没有和Panda自己打过交道,但是如果它是普通的numpy数组(熊猫的DataFrames都在后台),我会添加一列“技能”来枚举它们。
答案 3 :(得分:0)
您可以像这样利用.apply()
(@Jacco van Dorp提出了将所有发现的技能存储在同一列中的可靠建议,我同意这可能是解决问题的最佳方法):
df = pd.DataFrame([['Engineer','Firm','AERO1','Work with python and Django'],
['IT','Dell','ITD4','Work with Django and R'],
['Office Assistant','Dental','OAD3','Coordinate schedules'],
['QA Engineer','Factory','QA2','Work with R and python'],
['Mechanic','Autobody','AERO1','Love the movie Django']],
columns=['job_title','company','job_label','description'])
哪种产量:
job_title company job_label description
0 Engineer Firm AERO1 Work with python and Django
1 IT Dell ITD4 Work with Django and R
2 Office Assistant Dental OAD3 Coordinate schedules
3 QA Engineer Factory QA2 Work with R and python
4 Mechanic Autobody AERO1 Love the movie Django
然后定义您的技能和清单理解力,以传递给.apply()
:
skills = ['python','R','Django']
df['skills'] = df.apply(lambda x: [i for i in skills if i in x['description'].split()], axis=1)
哪一列产生:
skills
0 [python, Django]
1 [R, Django]
2 []
3 [python, R]
4 [Django]
如果您仍然希望针对每种技能使用单独的列,那么我也可以编辑答案以提供相应的信息。