python - 用于 XML 到 DataFrame 转换功能的 RAM 崩溃
问题描述
我创建了以下将 XML 文件转换为 DataFrame 的函数。此功能适用于小于 1 GB 的文件,任何大于 RAM(13GB Google Colab RAM)崩溃的文件。如果我在 Jupyter Notebook(4GB 笔记本电脑 RAM)上本地尝试,也会发生同样的情况。有没有办法优化代码?
代码
#Libraries
import pandas as pd
import xml.etree.cElementTree as ET
#Function to convert XML file to Pandas Dataframe
def xml2df(file_path):
#Parsing XML File and obtaining root
tree = ET.parse(file_path)
root = tree.getroot()
dict_list = []
for _, elem in ET.iterparse(file_path, events=("end",)):
if elem.tag == "row":
dict_list.append(elem.attrib) # PARSE ALL ATTRIBUTES
elem.clear()
df = pd.DataFrame(dict_list)
return df
XML 文件的一部分('Badges.xml')
<badges>
<row Id="82946" UserId="3718" Name="Teacher" Date="2008-09-15T08:55:03.923" Class="3" TagBased="False" />
<row Id="82947" UserId="994" Name="Teacher" Date="2008-09-15T08:55:03.957" Class="3" TagBased="False" />
<row Id="82949" UserId="3893" Name="Teacher" Date="2008-09-15T08:55:03.957" Class="3" TagBased="False" />
<row Id="82950" UserId="4591" Name="Teacher" Date="2008-09-15T08:55:03.957" Class="3" TagBased="False" />
<row Id="82951" UserId="5196" Name="Teacher" Date="2008-09-15T08:55:03.957" Class="3" TagBased="False" />
<row Id="82952" UserId="2635" Name="Teacher" Date="2008-09-15T08:55:03.957" Class="3" TagBased="False" />
<row Id="82953" UserId="1113" Name="Teacher" Date="2008-09-15T08:55:03.957" Class="3" TagBased="False" />
我也尝试了SAX
代码,但我得到了相同的 RAM Exhausted 错误。导入 xml.sax
import xml.sax
class BadgeHandler(xml.sax.ContentHandler):
def __init__(self):
self.row = None
self.row_data = []
self.df = None
# Call when an element starts
def startElement(self, tag, attributes):
if tag == 'row':
self.row = attributes._attrs
# Call when an elements ends
def endElement(self, tag):
if self.row and tag == 'row':
self.row_data.append(self.row)
def endDocument(self):
self.df = pd.DataFrame(self.row_data)
LOAD_FROM_FILE = True
handler = BadgeHandler()
if LOAD_FROM_FILE:
print('loading from file')
# 'rows.xml' is a file that contains your XML example
xml.sax.parse('/content/Badges.xml', handler)
else:
print('loading from string')
xml.sax.parseString(xml_str, handler)
print(handler.df)
解决方案
您正在将文件加载到内存中并对其进行迭代。
import pandas as pd
from lxml import etree
def xml2df(file_path):
dict_list = []
with open(file_path, "rb") as f:
for _, elem in etree.iterparse(f, events=("end",)):
if elem.tag == "row":
dict_list.append(elem.attrib)
#elem.clear()
return pd.DataFrame(dict_list)
推荐阅读
- ruby-on-rails - RoR - Bundler 找不到 gem 的兼容版本
- python - 如何在 Python 中的循环中追加一个空列表
- azure - 用于获取 XML 节点和子节点 xml 的液体模板,因为它是 json 格式
- python - Python没有从模块中导入函数
- c++ - 如何使用 MV 在 Qt 模型中实现层次结构?
- java - 如何查找 Lombok 生成的未使用的类
- ruby - 为什么 Ruby 扩展(Peng Lv)不起作用?
- python - 在 For 和 If 循环中迭代字典的键
- javascript - 如何在 React/Preact 应用程序中运行常规 JavaScript
- vba - Powerpoint Macro VBA - 选择“幻灯片图像”复选框