【问题标题】:Exporting Tokenized SpaCy result into Excel or SQL tables将标记化 SpaCy 结果导出到 Excel 或 SQL 表中
【发布时间】:2018-11-25 23:09:08
【问题描述】:

我正在使用 SpaCyPandas 来获得一个用词性 (POS) 导出标记化的句子以 excel。代码如下:

import spacy
import xlsxwriter
import pandas as pd
nlp = spacy.load('en_core_web_sm')
text ="""He is a good boy."""
doc = nlp(text)
for token in doc:
    x=[token.text, token.lemma_, token.pos_, token.tag_,token.dep_,token.shape_, token.is_alpha, token.is_stop]
    print(x)

当我print(x)我得到以下信息:

['He', '-PRON-', 'PRON', 'PRP', 'nsubj', 'Xx', True, False]
['is', 'be', 'VERB', 'VBZ', 'ROOT', 'xx', True, True]
['a', 'a', 'DET', 'DT', 'det', 'x', True, True]
['good', 'good', 'ADJ', 'JJ', 'amod', 'xxxx', True, False]
['boy', 'boy', 'NOUN', 'NN', 'attr', 'xxx', True, False]
['.', '.', 'PUNCT', '.', 'punct', '.', False, False]

在令牌循环中,我添加了 DataFrame,如下所示: 文档中的令牌:

for token in doc:
    x=[token.text, token.lemma_, token.pos_, token.tag_,token.dep_,token.shape_, token.is_alpha, token.is_stop]
    df=pd.Dataframe(x)
    print(df)

现在,我统计得到以下格式:

  0
0      He
1  -PRON-
2    PRON
3     PRP
4   nsubj
5      Xx
6    True
7   False   
........
........

但是,当我尝试使用 Pandas 将输出 (df) 导出到 excel 作为以下代码时,它只显示列中 x 的最后一次迭代

df=pd.DataFrame(x)
writer = pd.ExcelWriter('pandas_simple.xlsx', engine='xlsxwriter')
df.to_excel(writer,sheet_name='Sheet1')

输出(在 Excel 表中):

0
0      .
1      .
2  PUNCT
3      .
4  punct
5      .
6  False
7  False

在这种情况下,如何在新列中一个接一个地进行所有迭代,如下所示?

 0     He      is   ….
1    -PRON-    be   ….
2     PRON    VERB  ….
3     PRP      VBZ  ….
4    nsubj     ROOT ….
5      Xx      xx   ….
6    True     True  ….
7    False   True   ….

【问题讨论】:

  • 数据框的转置会更有意义。
  • 使用 df.append() 逐行添加
  • @EvgenyPogrebnyak,怎么样?你能告诉我如何使用 df.append 更改它吗?
  • 尝试通过pandas.pydata.org/pandas-docs/stable/10min.html#object-creation,没有什么大的困难,如果没有成功就回信。由于缺少编译器,我在安装SpaCy 时遇到问题,因此无法为您提供快速准备好的代码。

标签: pandas xlsxwriter spacy


【解决方案1】:

如果您还没有您的版本:

import pandas as pd

rows =[
    ['He', '-PRON-', 'PRON', 'PRP', 'nsubj', 'Xx', True, False],
    ['is', 'be', 'VERB', 'VBZ', 'ROOT', 'xx', True, True],
    ['a', 'a', 'DET', 'DT', 'det', 'x', True, True],
    ['good', 'good', 'ADJ', 'JJ', 'amod', 'xxxx', True, False],
    ['boy', 'boy', 'NOUN', 'NN', 'attr', 'xxx', True, False],
    ['.', '.', 'PUNCT', '.', 'punct', '.', False, False],
    ]

headers = ['text', 'lemma', 'pos', 'tag', 'dep', 
           'shape', 'is_alpha', 'is_stop']

# example 1: list of lists of dicts
#following  https://stackoverflow.com/a/28058264/1758363
d = []
for row in rows:
    dict_ = {k:v for k, v in zip(headers, row)}
    d.append(dict_)
df = pd.DataFrame(d)[headers] 

# example 2: appending dicts 
df2 = pd.DataFrame(columns=headers)
for row in rows:
    dict_ = {k:v for k, v in zip(headers, row)}
    df2 = df2.append(dict_, ignore_index=True)

#example 3: lists of dicts created with map() function
def as_dict(row):
    return {k:v for k, v in zip(headers, row)}

df3 = pd.DataFrame(list(map(as_dict, rows)))[headers]     

def is_equal(df_a, df_b):
    """Substitute for pd.DataFrame.equals()"""
    return (df_a == df_b).all().all()

assert is_equal(df, df2)
assert is_equal(df2, df3)

【讨论】:

  • 谢谢@Evengy。我将尝试这段代码,看看它如何适应这种情况。顺便说一句,在处理之后,我终于使用了一个替代库(CSV lib)将输出作为字典导入,它可以工作,但我有 CSV 作为输出而不是 excel,所以我必须经历从 CSV 到的第二轮转换擅长。我确实觉得 Pandas DataFrame 在某种程度上与 SpaCy 提供的内容不完全兼容,因为通过 CSV 在几行内相对容易
  • 你可以使用csv,如果你更喜欢它,它只是没有出现在你想要持久/保存数据的问题中,而是关于使用pandas。希望您不会对转换想法完全不满意 - SpaCy 没有任何特殊类型的输出,我猜只是命名元组。无论如何都要避免使用 Excel 作为格式来保存中间数据并确保单词在行中,而不是在列中。
  • @Evengy,只是对您的代码的快速反馈。当数据(行)是统计数组时,您的所有 3 种方法都可以完美运行。然而,一旦它被 SpaCy 称为“令牌”,就会弹出各种错误。我的感觉是,SPaCY 的 NLP 参数处理循环的方式不适合 Pandas 数据框架。使用像 CSV (CSV.DicWriter) 这样的原始库可以在几行内完成这项工作,然后这个 Pandas 可以将其进一步带到 Excel。无论如何感谢您的意见,如果您有任何其他意见,请分享您的想法。
  • 很高兴您为您的项目整理了它!你如何在 Windows 上编译 SpaCy 来安装?有测试编译器的命令吗?我安装了 Visual Studio,但 pip install spacyerror: command 'cl.exe' failed: No such file or directory 错误而停止。
  • 在Conda环境(Anaconda)下试试。我认为 Spacy 有自己的要求,最好单独安装(从根 Python 安装)。
【解决方案2】:

一些更短的代码:

import spacy
import pandas as pd
nlp = spacy.load('en_core_web_sm')
text ="""He is a good boy."""
param = [[token.text, token.lemma_, token.pos_, 
          token.tag_,token.dep_,token.shape_, 
          token.is_alpha, token.is_stop] for token in nlp(text)]
df=pd.DataFrame(param)
headers = ['text', 'lemma', 'pos', 'tag', 'dep', 
           'shape', 'is_alpha', 'is_stop']
df.columns = headers  

【讨论】:

  • 谢谢。刚收到ValueError: Length mismatch: Expected axis has 6 elements, new values have 8 elements。所以我尝试了df WITHOUT .transpose(),它完美地工作并符合目的。 (正如你提到的,在行中比在列中更好地使用文本 sn-ps)
  • 编辑时没有.transpose(),确实有错误。
猜你喜欢
  • 1970-01-01
  • 2014-12-18
  • 1970-01-01
  • 2023-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多