在Python中以高效的方式清理数据

在Python中以高效的方式清理数据,python,python-2.7,nlp,Python,Python 2.7,Nlp,我有以下格式的数据: 顶部(PP-LOC(IN)(NP(DT an)(NNP十月)(CD 19)(NN评论)(PP(IN of)(NP()(NP-TTL(DT The)(NN厌世者)))(NN)(在at)(NP(NNP芝加哥)(POS的)(NNP古德曼)(NNP剧院)))(PRN(-LRB--LRB-)()(s-HLN(NP-SBJ(VBN复兴)(NNS经典之作)(VP(VBP)(NP(DT the)(NN舞台)(PP-LOC(IN)(NP(NNP Windy)(NNP城市)(NN舞台)(NP-

我有以下格式的数据:

顶部(PP-LOC(IN)(NP(DT an)(NNP十月)(CD 19)(NN评论)(PP(IN of)(NP
(NP-TTL(DT The)(NN厌世者))(NN)(在at)(NP(NNP芝加哥)(POS的)(NNP古德曼)(NNP剧院)))(PRN(-LRB--LRB-)
)(s-HLN(NP-SBJ(VBN复兴)(NNS经典之作)(VP(VBP)(NP(DT the)(NN舞台)(PP-LOC(IN)(NP(NNP Windy)(NNP城市)(NN舞台)(NP-TMP(NN休闲)(CC&(NNS艺术)(-RRB--/RRB))<(NP-SBJ-2)(NP(NP(DT)(NN角色)(PP(在of中)(NP(NNP Celimene)(,)(VP(VBN扮演)(NP(-NONE-*)(PP(在by中)(NP-LGS(NNP Kim)(,))(VP(VBD was)(VP(ADVP-MNR(RB错误地)(VBN属性)(NP(-NONE-*-2))(PP-CLR(NP(NNP-Christina)(NNP-Haag(…

(顶部(NP-SBJ(NNP Ms)(NNP Haag)
)(VP(VBZ播放)(NP(NNP ELANTI)(…)

……(还有7000多个……)

此数据取自一份报纸。新行是一个新句子(以“TOP”开头) 根据这些数据,我只需要每个句子的粗体部分(不带括号):

(IN In)(DT an) (NNP Oct.) (CD 19) (NN review) (IN of) (`` ``) (DT The) (NN Misanthrope)   ('' '')  (IN at)  (NNP Chicago) (POS 's) (NNP Goodman) (NNP Theatre)(-LRB- -LRB-) (`` ``)     (VBN Revitalized) (NNS Classics) (VBP Take) (DT the) (NN Stage)  (IN in)   (NNP Windy) (NNP    City) (, ,) ('' '') (NN Leisure) (CC &) (NNS Arts) (-RRB- -RRB-)(, ,) (DT the) (NN role)(IN of)  (NNP Celimene) (, ,) (VBN played) (-NONE- *)(IN by)(NNP Kim) (NNP Cattrall) (, ,) (VBD was)  (RB mistakenly)(VBN attributed) (-NONE- *-2) (TO to)(NNP Christina) (NNP Haag) (. .)

(NNP Ms.) (NNP Haag) (VBZ plays)(NNP Elianti)(. .)
我尝试了以下方法:

f = open('filename')
data = f.readlines()
f.close()
这一部分是为每一行装箱一个元组数组(使用正则表达式):

这需要很长时间,所以我不知道它是否正确

你知道如何有效地做这件事吗

谢谢

哈达斯试试这个:

import re

f = open('filename')
data = f.readlines()
f.close()
tag_word_train = numpy.empty((5000), dtype = 'object')
exp = re.compile("\([^()]*\)")

i = 0

for line in data:
    #out = re.findall(exp, data)
    #print(out)
    tag_word_train[i] = re.findall(exp, data)               
    i = i + 1
分解正则表达式:

\(
匹配左括号

[^()]*
匹配零个或多个非左括号或右括号的字符

\)
匹配右括号

(我假设您想要的是本身不包含括号的术语。如果我的假设错误,正则表达式将不会执行您想要的操作)。

nltk
具有可能适合您需要的功能。特别是,您需要使用类方法:


nltk.tree
提供了在解析中读取和提取输出中所需的单词和词性标记对的函数:

>>> import nltk.tree
>>> t = nltk.tree.Tree.fromstring("(TOP (S (NP-SBJ (NNP Ms.) (NNP Haag) ) (VP (VBZ plays) (NP (NNP Elianti) )) (. .) ))")
>>> t.pos()
[('Ms.', 'NNP'), ('Haag', 'NNP'), ('plays', 'VBZ'), ('Elianti', 'NNP'), ('.', '.')]

@Marcin你在编辑之前读过这个问题吗?你的编辑把OP提到的粗体部分删掉了。对不起。太快了。数据从哪里来?
Stanford Parser
nltk
(其他什么?)?你好,Reut,我不知道…@Hadas,正如你所知-这些数据应该被建模为一棵树。使用正则表达式可以进行简单的练习,但如果这是一个你正在进行的项目,请查看常见NLP库如何处理它。我在“out”中得到一个错误。此外,我希望每一行数据都是单独的(在列表、数组或类似的东西中)我不确定你的答案是否如此。谢谢你的回答当我对你提供的上述输入使用我的答案时,我得到了你想要的输出。我已经编辑了我的答案,以展示如何将其与你现有的代码结合起来,以防出现问题。如果你想要存储输出,那么就不要使用
out=re.findall(exp,data)
打印(out)
您想要的
标记单词\u train[i]=re.findall(exp,data)
(我不知道numpy,但我假设您知道并且在那里声明了正确的列表类型)。
>>> import nltk.tree
>>> nltk.tree.Tree.fromstring("(S (NP (DT The) (N cat)) (VP (V ran)))")
Tree('S', [Tree('NP', [Tree('DT', ['The']), Tree('N', ['cat'])]), Tree('VP', [Tree('V', ['ran'])])])
>>> import nltk.tree
>>> t = nltk.tree.Tree.fromstring("(TOP (S (NP-SBJ (NNP Ms.) (NNP Haag) ) (VP (VBZ plays) (NP (NNP Elianti) )) (. .) ))")
>>> t.pos()
[('Ms.', 'NNP'), ('Haag', 'NNP'), ('plays', 'VBZ'), ('Elianti', 'NNP'), ('.', '.')]