我必须从预先存在的文本文件中复制信息并在同一行上添加pos标签并将其写入新文件,但我不知道如何获得正确的输出,提前感谢。
我当前的输出:
0 5 1001 China
5 7 1002 's
8 17 1003 state-run
18 23 1004 media
24 27 1005 say
28 29 1006 a
NNP POS JJ NNS VBP DT
法典:
import sys
import nltk
def main():
list1 = []
read = open("en.tok.off", "r")
data = read.read()
result = ''.join([i for i in data if not i.isdigit()])
result = result.split()
data3 = nltk.pos_tag(result)
words, tags = zip(*data3)
tags = " ".join(tags)
print(tags)
outfile = open("en.tok.off.pos", "w")
outfile.write(data)
outfile.write(tags)
outfile.close()
main()
我希望 NNP 位于 0 5 1001 China
的第五列上,POS
在 5 7 1002 's
之后在同一行上,等等。
期望输出:
0 5 1001 China NNP
5 7 1002 's POS
8 17 1003 state-run JJ
与其扔掉数字(这也会丢弃文本中的数字!(,而是收集所有内容并提取第四列进行标记。
data = read.read()
rows = [ line.split() for line in data.splitlines() ]
words = [ row[3] for row in rows ]
tagged = nltk.pos_tag(words)
然后你可以像这样把这些碎片重新组合在一起。
tagged_rows = [ row + [ tw[1] ] for row, tw in zip(rows, tagged) ]
(在相对较新的 Python 版本中,您可以进一步压缩上述内容(。另一种方法是使用像 numpy
或 pandas
这样的库,它允许您向数据添加列。但我认为这种方法更简单,因此更可取。
使用最新的nltk
版本 (v3.2.4(,有一个align_tokens
函数可能对令牌偏移量(前两列(有所帮助。
至于将POS打印为最后一列,只需将每个单词所需的元素放入列表中并使用str.join()
功能即可,例如:
>>> x = ['a', 'b', 'c']
>>> print ('t'.join(x))
a b c
>>> x.append('d')
>>> print ('t'.join(x))
a b c d
特定于您的代码:
[在]:
$ cat test.txt
China's state-run media say a
[代码]:
from nltk.tokenize.treebank import TreebankWordTokenizer
from nltk.tokenize.util import align_tokens
from nltk import pos_tag
tb = TreebankWordTokenizer()
with open('test.txt') as fin:
for line in fin:
text = line.strip()
tokens = tb.tokenize(text)
tagged_tokens = pos_tag(tokens)
offsets = align_tokens(tokens, text)
for (start, end), (tok, tag) in zip(offsets, tagged_tokens):
print ('t'.join([str(start), str(end), tok, tag]))
[输出]:
0 5 China NNP
5 7 's POS
8 17 state-run JJ
18 23 media NNS
24 27 say VBP
28 29 a DT