【问题标题】:Store lxml.etree._ElementTree objects in dataframe: TypeError: can't pickle lxml.etree._ElementTree objects在数据框中存储 lxml.etree._ElementTree 对象:TypeError: can't pickle lxml.etree._ElementTree objects
【发布时间】:2020-12-05 09:02:43
【问题描述】:

我尝试将 lxml.etree._ElementTree 对象存储在数据框中。不幸的是,熊猫无法识别这些物体。有没有办法将它们仍然存储在数据框中,或者是否有另一种方法可以将所有信息存储在具有良好读/写速度和文件大小的单个文件中?

这是一个重新创建错误的示例:

import pandas as pd

import lxml
from lxml import etree

s = '''<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>'''

doc = etree.fromstring(s)
root = etree.ElementTree(doc)

df = pd.DataFrame(data = [["name1", "date1", root]], columns = ["name", "date", "root"])
df.to_pickle(r"D:\test\test.pkl")
# TypeError: can't pickle lxml.etree._ElementTree objects

追溯:

Traceback (most recent call last):

  File "<...>", line 2, in <module>
    df.to_pickle(r"D:\test\test.pkl")

  File "...\Anaconda\envs\...\lib\site-packages\pandas\core\generic.py", line 2771, in to_pickle
    to_pickle(self, path, compression=compression, protocol=protocol)

  File "...\Anaconda\envs\...\lib\site-packages\pandas\io\pickle.py", line 76, in to_pickle
    f.write(pickle.dumps(obj, protocol=protocol))

TypeError: can't pickle lxml.etree._ElementTree objects

【问题讨论】:

  • 他们进入了数据框,只是你可以通过 pickle 存储 lxml 对象。由于 lxml 元素仍然引用原始文档,因此它不太可能是您想要做的。您可以只存储原始 xml 字符串(或重新序列化子树)。
  • 非常感谢您的反馈,我知道它在 df 中。我的意图是拥有一种快速的读/写格式来存储大量具有合适文件大小的 xml。由于我注意到 pandas 中 csv 和 pkl 在速度方面的极端差异,所以 .pkl 最初是有意义的。所以你会建议将字符串保存在数据框中而不是 ElementTree 或者我在那里误解了你?
  • @tdelaney 你的评论让我走上了我认为的正确轨道。谢谢!我在其他帖子中对您的一些答案进行了投票,因为我无法奖励评论的声誉。
  • 是的,我认为存储字符串比尝试存储 DOM 更好。那里有可能很方便的 XML 数据库,但我没有使用它们的经验。如何最好地存储数据取决于您以后想用它做什么。不过,这是一个很大的话题!

标签: python pandas lxml pickle


【解决方案1】:

对于未来的读者,通过在保存之前将 etree 转换为字符串来修复它:

df["root"] = df["root"].map(lambda x: etree.tostring(x, encoding='utf8', method='xml'))
df.to_pickle(r"D:\test.pkl")


df = pd.read_pickle(r"D:\test.pkl")
df["root"] = df["root"].map(etree.fromstring).map(etree.ElementTree)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-11
    • 1970-01-01
    • 1970-01-01
    • 2018-07-20
    • 2018-06-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多