我大约有1000个XML文件,每个文件的大小为250 MB。我需要从中提取一些数据并写入CSV。 不能有重复的条目。
我有一个配备4GB RAM和AMD A8处理器的系统。
我已经在这里浏览过一些以前的文章,但是它们似乎并不能回答我的问题。
我已经用Python编写了代码,并在示例XML上对其进行了测试,并且效果很好。
但是,当我在所有文件上使用它并且必须中途终止该过程时,它非常慢(每个文件将近15分钟)。
什么是加快该过程的最佳解决方案?
这是代码
path='data/*.xml'
t=[]
for fname in glob.glob(path):
print('Parsing ',fname)
tree=ET.parse(fname)
root=tree.getroot()
x=root.findall('//Article/AuthorList//Author')
for child in x:
try:
lastName=child.find('LastName').text
except AttributeError:
lastName=''
try:
foreName=child.find('ForeName').text
except AttributeError:
foreName=''
t.append((lastName,foreName))
print('Parsed ',fname)
t=set(t)
我想要最快的方法来获取条目,没有任何重复的值。 (也许存储在某个数据库中,而不是存储在变量t中,由于有更多的可用RAM,因此将每个条目存储在数据库中会加速吗?-无论我需要采用哪种方法进行操作)
答案 0 :(得分:4)
不要将结果写入Python列表,而是创建具有UNIQUE
约束的数据库表,并将所有结果写入该表。完成所有写操作后,将DB表转为csv。
如果您不希望有任何其他依赖关系来写入数据库,建议您使用sqlite3
,因为它在任何最新的Python安装中都是开箱即用的。
以下是一些入门代码:
import sqlite3
conn = sqlite3.connect('large_xml.db') # db will be created
cur = conn.cursor()
crt = "CREATE TABLE foo(fname VARCHAR(20), lname VARCHAR(20), UNIQUE(fname, lname))"
cur.execute(crt)
conn.commit()
path='data/*.xml'
for fname in glob.glob(path):
print('Parsing ',fname)
tree=ET.parse(fname)
root=tree.getroot()
x=root.findall('//Article/AuthorList//Author')
count = 0
for child in x:
try:
lastName=child.find('LastName').text
except AttributeError:
lastName=''
try:
foreName=child.find('ForeName').text
except AttributeError:
foreName=''
cur.execute("INSERT OR IGNORE INTO foo(fname, lname) VALUES(?, ?)", (foreName, lastName))
count += 1
if count > 3000: # commit every 3000 entries, you can tune this
count = 0
conn.commit()
print('Parsed ',fname)
填充数据库后,按以下步骤将其转储到csv:
sqlite3 -header -csv large_xml.db "select * from foo;" > dump.csv
此外,尝试使用更快的解析方式。
此外,如果.text
属性通常是可用的,
以下内容可能比异常处理要快:
lastName = getattr(child.find('LastName'), 'text', '')