使用 for 循环从标记化文本中删除标点符号
Remove punctuation marks from tokenized text using for loop
我正在尝试从 python 中的标记化文本中删除标点符号,如下所示:
word_tokens = ntlk.tokenize(text)
w = word_tokens
for e in word_tokens:
if e in punctuation_marks:
w.remove(e)
这有点管用,我设法删除了很多标点符号,但由于某些原因,word_tokens 中的很多标点符号仍然存在。
如果我再次 运行 代码,它会再次删除更多的标点符号。 运行 将相同的代码输入 3 次后,所有标记都将被删除。为什么会这样?
punctuation_marks 是列表、字符串还是字典似乎并不重要。我还尝试遍历 word_tokens.copy() ,它做得更好一些,它第一次几乎删除了所有标记,第二次也删除了所有标记。
有没有一种简单的方法可以解决此问题,以便仅 运行 代码一次就足够了?
您正在从迭代的同一个列表中删除元素。您似乎已经意识到潜在的问题,这就是您添加以下行的原因:
w = word_tokens
然而,该行实际上并没有创建 word_tokens 引用的对象的副本,它只是使 w 引用了同一个对象。为了创建副本,您可以使用切片运算符,将上面的行替换为:
w = word_tokens[:]
我建议您尝试使用正则表达式并将您的结果附加到新列表中,而不是直接操作 word_tokens
的结果:
word_tokens = ntlk.tokenize(text)
w_ = list()
for e in word_tokens:
w_.append(re.sub('[.!?\-]', e))
您正在修改实际 word_tokens
,这是错误的。
例如,假设您有类似 A?!B
的内容,其索引为:A:0, ?:1, !:2, B:3
。你的 for 循环有一个计数器(比如 i
),它在每个循环中增加。假设您删除了使数组索引向后移动的 ?
(意味着 i=1
)(新索引是:A:0, !:1, B:2
)和您的计数器递增(i=2
)。所以你在这里漏掉了 !
字符!
最好不要弄乱原来的字符串,直接复制到一个新的。
为什么不添加不是标点符号的标记呢?
word_tokens = ntlk.tokenize(text)
w = list()
for e in word_tokens:
if e not in punctuation_marks:
w.append(e)
建议:
我看到你正在创建单词标记。如果是这种情况,我建议您在标记文本之前删除标点符号。您可以使用已经可用的翻译功能(在字符串库下)。
# Import the library
import string
# Initialize the translate to remove punctuations
tr = str.maketrans("", "", string.punctuation)
# Remove punctuations
text = text.translate(tr)
# Get the word tokens
word_tokens = ntlk.tokenize(text)
如果你想做句子标记化,那么你可以做如下的事情:
from nltk.tokenize import sent_tokenize
texts = sent_tokenize(text)
for i in range(0, len(texts))
texts[i] = texts[i].translate(tr)
我正在尝试从 python 中的标记化文本中删除标点符号,如下所示:
word_tokens = ntlk.tokenize(text)
w = word_tokens
for e in word_tokens:
if e in punctuation_marks:
w.remove(e)
这有点管用,我设法删除了很多标点符号,但由于某些原因,word_tokens 中的很多标点符号仍然存在。 如果我再次 运行 代码,它会再次删除更多的标点符号。 运行 将相同的代码输入 3 次后,所有标记都将被删除。为什么会这样?
punctuation_marks 是列表、字符串还是字典似乎并不重要。我还尝试遍历 word_tokens.copy() ,它做得更好一些,它第一次几乎删除了所有标记,第二次也删除了所有标记。 有没有一种简单的方法可以解决此问题,以便仅 运行 代码一次就足够了?
您正在从迭代的同一个列表中删除元素。您似乎已经意识到潜在的问题,这就是您添加以下行的原因:
w = word_tokens
然而,该行实际上并没有创建 word_tokens 引用的对象的副本,它只是使 w 引用了同一个对象。为了创建副本,您可以使用切片运算符,将上面的行替换为:
w = word_tokens[:]
我建议您尝试使用正则表达式并将您的结果附加到新列表中,而不是直接操作 word_tokens
的结果:
word_tokens = ntlk.tokenize(text)
w_ = list()
for e in word_tokens:
w_.append(re.sub('[.!?\-]', e))
您正在修改实际 word_tokens
,这是错误的。
例如,假设您有类似 A?!B
的内容,其索引为:A:0, ?:1, !:2, B:3
。你的 for 循环有一个计数器(比如 i
),它在每个循环中增加。假设您删除了使数组索引向后移动的 ?
(意味着 i=1
)(新索引是:A:0, !:1, B:2
)和您的计数器递增(i=2
)。所以你在这里漏掉了 !
字符!
最好不要弄乱原来的字符串,直接复制到一个新的。
为什么不添加不是标点符号的标记呢?
word_tokens = ntlk.tokenize(text)
w = list()
for e in word_tokens:
if e not in punctuation_marks:
w.append(e)
建议: 我看到你正在创建单词标记。如果是这种情况,我建议您在标记文本之前删除标点符号。您可以使用已经可用的翻译功能(在字符串库下)。
# Import the library
import string
# Initialize the translate to remove punctuations
tr = str.maketrans("", "", string.punctuation)
# Remove punctuations
text = text.translate(tr)
# Get the word tokens
word_tokens = ntlk.tokenize(text)
如果你想做句子标记化,那么你可以做如下的事情:
from nltk.tokenize import sent_tokenize
texts = sent_tokenize(text)
for i in range(0, len(texts))
texts[i] = texts[i].translate(tr)