繁体   English   中英

解析大型 XML 文件时出现 Memory 错误

[英]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 处理,该处理以增量方式读取树,而不是一次全部读取。 在每次迭代中,从属性字典或TimeStepParticle元素上的文本中提取:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM