【问题标题】:How to apply pos_tag_sents() to pandas dataframe efficiently如何有效地将 pos_tag_sents() 应用于 pandas 数据帧
【发布时间】:2017-05-31 04:25:30
【问题描述】:

如果您希望对存储在 pandas 数据框中的一列文本进行 POS 标记,每行 1 个句子,那么 SO 上的大多数实现都使用 apply 方法

dfData['POSTags']= dfData['SourceText'].apply(
                 lamda row: [pos_tag(word_tokenize(row) for item in row])

NLTK 文档recommends using the pos_tag_sents() 用于有效标记多个句子。

这是否适用于本示例,如果适用,代码是否会像将 pso_tag 更改为 pos_tag_sents 一样简单,或者 NLTK 是否意味着段落的文本源

正如 cmets pos_tag_sents() 中提到的那样,旨在每次减少 preceptor 的负载但问题是如何做到这一点并且仍然在 pandas 数据框中生成一列?

Link to Sample Dataset 20kRows

【问题讨论】:

  • 你有多少行?
  • 20,000 行将是行数
  • 这不是问题。只需将该列提取为字符串列表,对其进行处理,然后将其添加到该列中返回到数据框。
  • 您能提供一个编码示例吗?
  • 您能提供数据示例吗?只需将您的 dataframe.head() 转储到 csv 文件中;P

标签: python python-3.x pandas nltk pos-tagger


【解决方案1】:

输入

$ cat test.csv 
ID,Task,label,Text
1,Collect Information,no response,cozily married practical athletics Mr. Brown flat
2,New Credit,no response,active married expensive soccer Mr. Chang flat
3,Collect Information,response,healthy single expensive badminton Mrs. Green flat
4,Collect Information,response,cozily married practical soccer Mr. Brown hierachical
5,Collect Information,response,cozily single practical badminton Mr. Brown flat

TL;DR

>>> from nltk import word_tokenize, pos_tag, pos_tag_sents
>>> import pandas as pd
>>> df = pd.read_csv('test.csv', sep=',')
>>> df['Text']
0    cozily married practical athletics Mr. Brown flat
1       active married expensive soccer Mr. Chang flat
2    healthy single expensive badminton Mrs. Green ...
3    cozily married practical soccer Mr. Brown hier...
4     cozily single practical badminton Mr. Brown flat
Name: Text, dtype: object
>>> texts = df['Text'].tolist()
>>> tagged_texts = pos_tag_sents(map(word_tokenize, texts))
>>> tagged_texts
[[('cozily', 'RB'), ('married', 'JJ'), ('practical', 'JJ'), ('athletics', 'NNS'), ('Mr.', 'NNP'), ('Brown', 'NNP'), ('flat', 'JJ')], [('active', 'JJ'), ('married', 'VBD'), ('expensive', 'JJ'), ('soccer', 'NN'), ('Mr.', 'NNP'), ('Chang', 'NNP'), ('flat', 'JJ')], [('healthy', 'JJ'), ('single', 'JJ'), ('expensive', 'JJ'), ('badminton', 'NN'), ('Mrs.', 'NNP'), ('Green', 'NNP'), ('flat', 'JJ')], [('cozily', 'RB'), ('married', 'JJ'), ('practical', 'JJ'), ('soccer', 'NN'), ('Mr.', 'NNP'), ('Brown', 'NNP'), ('hierachical', 'JJ')], [('cozily', 'RB'), ('single', 'JJ'), ('practical', 'JJ'), ('badminton', 'NN'), ('Mr.', 'NNP'), ('Brown', 'NNP'), ('flat', 'JJ')]]

>>> df['POS'] = tagged_texts
>>> df
   ID                 Task        label  \
0   1  Collect Information  no response   
1   2           New Credit  no response   
2   3  Collect Information     response   
3   4  Collect Information     response   
4   5  Collect Information     response   

                                                Text  \
0  cozily married practical athletics Mr. Brown flat   
1     active married expensive soccer Mr. Chang flat   
2  healthy single expensive badminton Mrs. Green ...   
3  cozily married practical soccer Mr. Brown hier...   
4   cozily single practical badminton Mr. Brown flat   

                                                 POS  
0  [(cozily, RB), (married, JJ), (practical, JJ),...  
1  [(active, JJ), (married, VBD), (expensive, JJ)...  
2  [(healthy, JJ), (single, JJ), (expensive, JJ),...  
3  [(cozily, RB), (married, JJ), (practical, JJ),...  
4  [(cozily, RB), (single, JJ), (practical, JJ), ... 

长篇大论:

首先,您可以将Text 列提取到字符串列表中:

texts = df['Text'].tolist()

然后你可以应用word_tokenize函数:

map(word_tokenize, texts)

请注意,@Boud 的建议几乎相同,使用df.apply

df['Text'].apply(word_tokenize)

然后将标记化的文本转储到字符串列表中:

df['Text'].apply(word_tokenize).tolist()

那么你可以使用pos_tag_sents:

pos_tag_sents( df['Text'].apply(word_tokenize).tolist() )

然后将列添加回 DataFrame:

df['POS'] = pos_tag_sents( df['Text'].apply(word_tokenize).tolist() )

【讨论】:

  • 您的 'TL;DR' 比 'In Long' 版本长 :)
  • @Louis Yang -- 有趣!而且,是的,比“长”部分更长。但我只是一步一步地完成了它并且工作正常。
【解决方案2】:

通过在每一行上应用pos_tag,每次都会加载感知器模型(代价高昂的操作,因为它从磁盘读取泡菜)。

如果您改为获取所有行并将它们发送到pos_tag_sents(需要list(list(str))),则模型会加载一次并用于所有。

请参阅source

【讨论】:

  • 您能否提供一个示例,以使用 pos_tag_sents() 和 pandas 数据框列作为源和总体目标,以便句子和标记输出位于同一行?
  • 我会在黑暗中刺伤,因为我对 Pandas 不太熟悉。也许像pos_tag_sents(map(word_tokenize, dfData['SourceText'].values()))
【解决方案3】:

将此分配给您的新列:

dfData['POSTags'] = pos_tag_sents(dfData['SourceText'].apply(word_tokenize).tolist())

【讨论】:

    猜你喜欢
    • 2018-04-08
    • 2019-11-27
    • 2015-12-21
    • 2021-09-21
    • 1970-01-01
    • 2014-10-31
    • 2015-09-13
    • 2020-05-28
    • 1970-01-01
    相关资源
    最近更新 更多