替换data.frame

时间:2017-02-03 12:01:43

标签: python

我有以下代码检查数据框中的句子是否在列表中。如果是这种情况,则应将部件替换为''。

import pandas as pd
input_set = pd.DataFrame([['Thanks for the mail Harry', 1], ['Thanks for mailing Harry', 1]], columns=('Sentence', 'ticketID'))


def reduceString(string, listSentences):
 for i in listSentences:
  new_string = string.replace(i, '')
  return(new_string)

listSentences = ['Thanks for the ']

for index, sentence in input_set.iterrows():
 string = reduceString(sentence['Sentence'], listSentences)
 print(string)

一切正常。

但是,我想通过包含diff模块使其更加强大。目标是不仅删除了确切的句子,而且删除了与x%相似的句子。

因此我尝试用这个来调整代码:

import difflib
def reduceString2(string, listSentences):
 for i in listSentences:
  ratio = difflib.SequenceMatcher(None, i, string).ratio()
  print(ratio)
  if(ratio > 0.6):
     new_string = string.replace(i, '')
  return(new_string)

但是,如果我现在尝试运行:

 for index, sentence in input_set.iterrows():
  string = reduceString2(df['Sentence'], listSentences)

它确实没有改变第二句,而确实触及了if语句的障碍。有人可以说明为什么没有替换相关文本吗?

1 个答案:

答案 0 :(得分:1)

首先,第一和第二算法完全不同;第一个将替换字符串中的任何位置的句子,而第二个将比较两个字符串总数是否相似(不是有相似的子序列)。

其次,即使stringi相似,您也试图替换string中不一定存在的子字符串。您可以使用SequenceMatcher中的某些方法找到要删除的正确位置:

import difflib
def reduceString2(string, listSentences):
 for i in listSentences:
  matcher = difflib.SequenceMatcher(None, i, string)
  ratio = matcher.ratio()
  print(ratio)
  if(ratio > 0.6):
     blocks = matcher.get_matching_blocks()
     b_first, b_last = blocks[0], blocks[-2]
     new_string = string[:b_first[1]] + string[b_last[1] + b_last[2]:]
  return(new_string)

然而,这种方法特别会给你:

mail Harry
Harry

因为'Thanks for the '中的最后一个空格与第二个句子中Harry之前的空格匹配。另一个选择是只删除被替换的块,但这会给你:

mail Harry
mailingHarry

这可能不是你所期望的。所以你必须决定如何处理这些匹配的块。

此外,您可以考虑使用quick_ratio()real_quick_ratio()作为更快的过滤器(请参阅SequenceMatcher documentation),以及其他一些小问题,例如剥离和小写字符串。