[英]Memory error while parsing large XML files
我必须阅读大型 XML 文件以获取按列排列的 XML 信息的矩阵。
XML结构如下
Several lines of no structured heading
<TimeStep TS="1">
<Particle PT="1">
<![CDATA[100,1000]]>
</Particle>
<Particle PT="2">
<![CDATA[200,2000]]>
</Particle>
</TimeStep>
<Timestep TS="2">
<Particle PT="1">
<![CDATA[101,1001]]>
</Particle>
<Particle PT="2">
<![CDATA[202,2002]]>
</Particle>
</TimeStep>
and so on
目标矩阵结构是按列的,如下
第一列 = TimeStep TS
第 2 列 = 粒子 PT
第 3 列和第 4 列 = 方格内的数据
1 1 100 1000
1 2 200 2000
2 1 101 1001
2 2 202 2002
到目前为止,我设法做到了如下
import numpy as np
import xml.etree.ElementTree as ET
filename = 'ParticleTrack.xml'
xmlfile = ET.parse(filename)
tt = xmlfile.findall(".//Particle/../../[@TS]") # picks only TimeSteps with Particles in them (might be TimeSteps with no Particles in them)
data = []
for jj in tt:
ts = jj.get('TS')
pt = jj.findall(".//Particle[@PT]")
for ii in range(len(pt)):
data.append([ts, pt[ii].get('PT'), (pt[ii].text.split(",")[0]), (pt[ii].text.split(",")[1])])
data=np.array(data).astype(np.float)
我的电脑有 64GB 的 RAM,当 XML 文件略大于 10GB 时,我用完了 memory。 我正在一次加载整个 XML 文件并同时写入 output 矩阵。
我已经阅读了有关如何计时和 memory 使用 lxml、iterparse 等有效地流式解析大型 XML 文件的信息,但我不知道如何处理我的数据。
谢谢,我将不胜感激。
正如您所提到的,对于大型 XML 文件,请考虑iterparse
进行快速 stream 处理,该处理以增量方式读取树,而不是一次全部读取。 在每次迭代中,从属性字典或TimeStep和Particle元素上的文本中提取:
import numpy as np
from xml.etree.ElementTree import iterparse
#from cElementTree import iterparse # POSSIBLY FASTER
filename = 'ParticleTrack.xml'
data = []
for event, elem in iterparse(filename, events=("start", "end")):
if elem.tag == "TimeStep" and event == 'start':
TS = elem.attrib['TS']
elem.clear()
if elem.tag == "Particle" and event == 'start':
cdata = elem.text.split(',')
data.append([TS, elem.attrib['PT'], cdata[0], cdata[1]])
elem.clear()
mat = np.array(data).astype(np.float)
print(mat)
# [[1.000e+00 1.000e+00 1.000e+02 1.000e+03]
# [1.000e+00 2.000e+00 2.000e+02 2.000e+03]
# [2.000e+00 1.000e+00 1.010e+02 1.001e+03]
# [2.000e+00 2.000e+00 2.020e+02 2.002e+03]]
cElementTree 很慢,与 lxml、xpath 和 iters 一起工作使它更快,就像这样。
import lxml.etree as et
import numpy as np
def process_xml(filename):
parse_xml = et.ElementTree(et.fromstring(filename)).getroot()
items = []
for node in parse_xml.iter('ARTIKEL'):
ean = node.xpath('.//ARTIKELEAN/text()')
stock1 = node.xpath('.//INSTOCK/text()')
huidige_voorraad_excellent.append([ean,stock1])
dfcols_stock = ['ean','stock1']
items = pd.DataFrame(huidige_voorraad_excellent,columns=dfcols_stock)
items = items.applymap(lambda x: x if not isinstance(x, list) else x[0] if len(x) else '')
return items
data = process_xml(filename)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.