在熊猫中,如何从单词列表或单词集中选择数据框中的短语? - python

在Python3和熊猫中,我具有数据框:

df_projetos_api_final.info()                                                      
<class 'pandas.core.frame.DataFrame'>                                                      
Int64Index: 93631 entries, 1 to 93667                                                      
Data columns (total 21 columns):                                                           
AnoMateria                       93631 non-null object                                     
CodigoMateria                    93631 non-null object                                     
DescricaoIdentificacaoMateria    93631 non-null object                                     
DescricaoSubtipoMateria          93631 non-null object                                     
IndicadorTramitando              93631 non-null object                                     
NomeCasaIdentificacaoMateria     93631 non-null object                                     
NumeroMateria                    93631 non-null object                                     
ApelidoMateria                   891 non-null object                                       
DataApresentacao                 93631 non-null object                                     
DataLeitura                      54213 non-null object                                     
EmentaMateria                    93631 non-null object                                     
ExplicacaoEmentaMateria          9461 non-null object                                      
IndicadorComplementar            93631 non-null object                                     
DescricaoNatureza                54352 non-null object                                     
NomeAutor                        93100 non-null object                                     
IndicadorOutrosAutores           93214 non-null object                                     
CodigoParlamentar                49786 non-null object                                     
NomeParlamentar                  49786 non-null object                                     
NomeCompletoParlamentar          49786 non-null object                                     
UfParlamentar                    45613 non-null object                                     
DescricaoSituacao                78783 non-null object                                     
dtypes: object(21)                                                                         
memory usage: 8.2+ MB 

“ EmentaMateria”列在每一行中都有一系列句子。我计划从包含本列中任何一个或多个这些单词(或一组单词)的行中创建一个新的数据框:

str_choice = "MULHER|MULHERES|TRABALHO DOMESTICO|VIOLENCIA CONTRA A MULHER|VIOLENCIA DOMESTICA|VIOLENCIA DE GENERO|MARIA DA PENHA|ABORTO|ABORTAMENTO|INTERRUPCAO DE GRAVIDEZ|INTERRUPCAO DE GESTACAO|DIREITO REPRODUTIVO|DIREITOS REPRODUTIVOS|DIREITO A VIDA|CONCEPCAO|CONTRACEPCAO|CONTRACEPTIVO|MISOPROSTOL|MIFEPRISTONE|CYTOTEC|UTERO|GESTACAO|GRAVIDEZ|PARTO|VIOLENCIA OBSTETRICA|FETO|BEBE|CRIANCA|VIOLENCIA SEXUAL|FEMINICIDIO|MORTE DE MULHER|MORTE DE MULHERES|HOMICIDIO DE MULHER|HOMICIDIO DE MULHERES|ASSEDIO SEXUAL|ASSEDIO|ESTUPRO|VIOLENCIA SEXUAL|ABUSO SEXUAL|ESTUPRO DE VULNERAVEL|LICENCA MATERNIDADE|FEMININO|MULHER NEGRA|MULHERES NEGRAS|MULHERES QUILOMBOLAS|MULHERES INDIGENAS|NEGRAS|NEGRA|RACISMO|RACA|RACIAL|ABUSO SEXUAL|MATERNIDADE|MAE|AMAMENTACAO|SEXUALIDADE|SEXO|GENERO|FEMINISMO|MACHISMO|GUARDA DE FILHOS|GUARDA DOS FILHOS|IGUALDADE DE GENERO|IDENTIDADE DE GENERO|IDEOLOGIA DE GENERO|EDUCACAO SEXUAL|ESCOLA SEM PARTIDO|TRANSEXUAL|TRANSEXUALIDADE|MULHER TRANS|MULHERES TRANS|MUDANCA DE SEXO|READEQUACAO SEXUAL|EXPLORACAO SEXUAL|PROSTITUICAO|ORIENTACAO SEXUAL|HOMOSSEXUAL|HOMOSSEXUALIDADE|HOMOSSEXUALISMO|LESBICA|LESBICAS|DIREITO DOS HOMENS|EDUCACAO RELIGIOSA|DEUS|RELIGIAO|EDUCACAO DOMICILIAR|HOMESCHOOLING|CRECHE|EDUCACAO INFANTIL|CASAMENTO INFANTIL"  

所以我确实这样:

seleciona2 = df_projetos_api_final [df_projetos_api_final['EmentaMateria'].\
                               str.contains(str_choice, na=False)]

新生成的数据框已收集了多个包含一个或多个这些单词的句子。但是,许多行没有这些词,因为
“ ENCAMINHA AO SENADO FEDERAL,UM ADENDO代表S UGESTOES DE EMENDAS A
马六甲前波罗的海做联邦,参考阿尔泰拉索
特拉帕洛霍基金会计划-DE DESENVOLVIMENTO DO
联邦快递,VISANDO A ACRESCENTAR MAIS CZ 3.453.977.000,00
(TRES BILHOES,QUATROCENTOS E CINQUENTA E TRES MILHOES,NOVECENTOS E
SETENTA E SETE MIL CRUZADOS)AO PROJETO DE EXECUCAO DE OBRAS E
EQUIPAMENTOS DO SISTEMA DE EDUCACAO E CULURA。”

拜托,这是因为还在句子中搜索相似的单词吗?还是因为许多句子在某些单词之间有太多空格或换行符?

编辑7/12/2019

非常感谢所有朋友的关注。在您写完之后,我又去回顾了数据库,并再次提出了建议的代码。我得到了原始数据库,并带有巴西葡萄牙语的口音。我认为这是原始问题-我不知道原始基准已更改

我发现我正在使用的数据库已通过unidecode删除了葡萄牙语中的重音符号。所以我用带有重音符号的str_choice和原始数据库重复了测试,然后工作了-我还没有检查所有行,但是到目前为止我所看到的都是正确的

因此,新的str_choice(我使用了名称search_list)是这样的:

df_projetos_api_final['EmentaMateria'] = df_projetos_api_final['EmentaMateria'].str.upper()
search_list = ["MULHER", "MULHERES", "TRABALHO DOMÉSTICO", "VIOLÊNCIA CONTRA A MULHER", "VIOLÊNCIA DOMÉSTICA", "VIOLÊNCIA DE GÊNERO", "MARIA DA PENHA", "ABORTO", "ABORTAMENTO", "INTERRUPÇÃO DE GRAVIDEZ", "INTERRUPÇÃO DE GESTAÇÃO", "DIREITO REPRODUTIVO", "DIREITOS REPRODUTIVOS", "DIREITO À VIDA", "CONCEPÇÃO", "CONTRACEPÇÃO", "CONTRACEPTIVO", "MISOPROSTOL", "MIFEPRISTONE", "CYTOTEC", "ÚTERO", "GESTAÇÃO", "GRAVIDEZ", "PARTO", "VIOLÊNCIA OBSTÉTRICA", "FETO", "BEBÊ", "CRIANÇA", "VIOLÊNCIA SEXUAL", "FEMINICÍDIO", "MORTE DE MULHER", "MORTE DE MULHERES", "HOMICÍDIO DE MULHER", "HOMICÍDIO DE MULHERES", "ASSÉDIO SEXUAL", "ASSÉDIO", "ESTUPRO", "VIOLÊNCIA SEXUAL", "ABUSO SEXUAL", "ESTUPRO DE VULNERÁVEL", "LICENÇA MATERNIDADE", "FEMININO", "MULHER NEGRA", "MULHERES NEGRAS", "MULHERES QUILOMBOLAS", "MULHERES INDÍGENAS", "NEGRAS", "NEGRA", "RACISMO", "RAÇA", "RACIAL", "ABUSO SEXUAL", "MATERNIDADE", "MÃE", "AMAMENTAÇÃO", "SEXUALIDADE", "SEXO", "GÊNERO", "FEMINISMO", "MACHISMO", "GUARDA DE FILHOS", "GUARDA DOS FILHOS", "IGUALDADE DE GÊNERO", "IDENTIDADE DE GÊNERO", "IDEOLOGIA DE GÊNERO", "EDUCAÇÃO SEXUAL", "ESCOLA SEM PARTIDO", "TRANSEXUAL", "TRANSEXUALIDADE", "MULHER TRANS", "MULHERES TRANS", "MUDANÇA DE SEXO", "READEQUAÇÃO SEXUAL", "EXPLORAÇÃO SEXUAL", "PROSTITUIÇÃO", "ORIENTAÇÃO SEXUAL", "HOMOSSEXUAL", "HOMOSSEXUALIDADE", "HOMOSSEXUALISMO",  "LÉSBICA",  "LÉSBICAS",  "DIREITO DOS HOMENS", "EDUCAÇÃO RELIGIOSA",  "DEUS", "RELIGIÃO", "EDUCACÃO DOMICILIAR", "HOMESCHOOLING", "CRECHE",  "EDUCAÇÃO INFANTIL",  "CASAMENTO INFANTIL"]
mask = df_projetos_api_final['EmentaMateria'].str.contains('|'.join(search_list))
seleciona = df_projetos_api_final[mask]
seleciona.info()

python大神给出的解决方案

诊断
首先,让我们看一下为什么您的代码不起作用。 @jorijnsmit放弃了它(并共享一个useful answer),您的正则表达式匹配字符,无论它们在哪里。让我们用一个简单的例子来说明,我将在整个过程中使用它:
我们想匹配单词'app''he',所以我们构造一个与您的正则表达式非常相似的正则表达式。

strings_to_match = ['app', 'he']

match_pattern = '|'.join(strings_to_match) # "app|he"

我们使用交替运算符连接了要匹配的字符串,我们很高兴,对吗?感谢regex101的魔力,这是将我们的模式应用于几个字符串的结果(匹配放在方括号中):

[he]llo
brot[he]r
[app]lication
[he]
[app]le
h[app]ier
[app]
[he]ll

当我们只需要单词本身时,我们的模式将在任何地方匹配字符串'app''he'

正则表达式解决方案
我们该如何解决?我们的第一个想法可能是将模式更改为' app | he ',这确实解决了诸如'application'这样的字符串的问题。不幸的是,这并非万无一失。该模式无法识别'app'中的'I downloaded an app.'单词,这对我们来说是完全有效的。对我们来说幸运的是,正则表达式具有我们需要的解决方案:Word boundaries,由令牌'\b'表示,其原理相当不言自明。
以下是新模式'\bapp\b|\bhe\b'的一些结果:

'[he]'
'apple'
'happier'
' [app] '
'hell'
'I downloaded an [app]!'

正是我们所期望的!尽管它确实可以正常工作,但是不必要地很难理解该模式。通过将所有子字符串放入non-capturing group:'\b(?:app|he)\b',我们只能使用一组单词边界标记。捕获组可以对正则表达式的子集进行分组和捕获。在这种情况下,小组将返回与整个比赛相同的事物。一个非捕获组消除了这种冗余,同时仍然允许我们在逻辑上分离表达的一部分。
这是一个完整的程序,演示了如何构建模式并在Pandas Series上使用它:

import pandas as pd

test_strs = ['hello', 'brother', 'application', 'he', 'apple', 'happier', 'app', 'hell', ' app ',
             'I downloaded an app.']

test_series = pd.Series(data=test_strs)

strings_to_match = ['app', 'he']

match_pattern = fr"\b(?:{'|'.join(strings_to_match)})\b"  # "\b(?:app|he)\b"

match_res = test_series.str.contains(match_pattern, case=False)

print(match_res)的输出:

0    False
1    False
2    False
3     True
4    False
5    False
6     True
7    False
8     True
9     True
dtype: bool

关于其他解决方案的一些注意事项
1。
请注意,这些方法只能匹配单词,不能匹配任意子字符串。因此,它们实际上不是针对此特定问题的有效解决方案,仅出于完整性考虑而在此处进行介绍。
这与@FBruzzesi解决方案的样式相同,我们将其称为版本1。供参考:

# Convert string into list of strings
str_list = str_choice.split(|)

# Control if any word is in the sentence after splitting the sentence by space
df['has_match'] = df.apply(lambda r: [x for x in str_list if x in r['EmentaMateria'].split(' ')], axis=1)

#This will create a list of words you find, then you can filter only those which has a match
df = df[df.apply(lambda r: len(r['has_match'])>0, axis=1)]

当他们的解决方案收集所有匹配项时,我们只关心是否有匹配项。让我们看一下其解决方案的重构版本:版本2:

import pandas as pd

test_strs = ['hello', 'brother', 'application', 'he', 'apple', 'happier', 'app', 'hell', ' app ',
             'I downloaded an app.']

test_series = pd.Series(data=test_strs)

strings_to_match = ['app', 'he']

series_split = test_series.str.split()

match_res = series_split.map(lambda curr_words: any((curr_sub in curr_words for curr_sub in strings_to_match)))

与版本1不同,版本2将split()操作的数量减至最少(这是真正令人担忧的原因(我估计整列中大约有8,000,000个split()操作))。由于迭代次数取决于要匹配的子字符串的数量,因此它也应该更有效,子字符串的数量通常应少于要检查的字符串中的单词数。
2。
我已经看到一些关于regex参数的提及,我认为这些提及不清楚或具有误导性。是的,传递regex=False将匹配文字字符串,否,仅更改参数不会使您当前的代码正常工作(为什么?)。

我希望这是您在寻求规范答案时想到的事情。让我知道是否有任何不清楚的地方,或者您还有其他问题:)

在Flask中测试文件上传 - python

我在Flask集成测试中使用Flask-Testing。我有一个表单,该表单具有我要为其编写测试的徽标的文件上传,但是我不断收到错误消息:TypeError: 'str' does not support the buffer interface。我正在使用Python3。我找到的最接近的答案是this,但是它对我不起作用。这是我的许多尝…

如果__name__ =='__main__',则为Python的Powershell等效项: - python

我真的很喜欢python的功能,例如:if __name__ == '__main__': #setup testing code here #or setup a call a function with parameters and human format the output #etc... 很好,因为我可以将Python脚本文件…

当回复有时是一个对象有时是一个数组时,如何在使用改造时解析JSON回复? - java

我正在使用Retrofit来获取JSON答复。这是我实施的一部分-@GET("/api/report/list") Observable<Bills> listBill(@Query("employee_id") String employeeID); 而条例草案类是-public static class…

对于DataFrame的每一行,在给定条件的情况下获取第一列的索引到新列中 - python

这是我的数据框的一部分。data = [ ['1245', np.nan, np.nan, 1.0, 1.0, ''], ['1246', np.nan, 1.0, 1.0, 1.0, ''], ['1247', 1.0, 1.0, 1.0, 1.0, �…

Python-熊猫描述了抛出错误:无法散列的类型“ dict” - python

更新:我正在使用“ Socrata开源API”中的一些示例代码。我在代码中注意到以下注释:# First 2000 results, returned as JSON from API / converted to Python # list of dictionaries by sodapy. 我不熟悉JSON。我已经下载了一个数据集,并创建了一个包含大量…