我有一个数据集,大小范围为1-5亿个“盒子”对象,存储在SQLite数据库文件中,格式为:
[x1,y1,z1,x2,y2,z2,box_id]
目前我在python脚本中执行了类似的操作:
import sqlite3 as lite
box_data = lite.connect('boxes.db')
cur = box_data.cursor()
editor_cursor = box_data.cursor()
cur.execute("SELECT * FROM boxes")
while True:
row = cur.fetchone()
if row == None:
break
row_id = row[6]
x1_normalized = int(round(row[0]/smallest_box_size))
y1_normalized = int(round(row[1]/smallest_box_size))
z1_normalized = int(round(row[2]/smallest_box_size))
x2_normalized = int(round(row[3]/smallest_box_size))
y2_normalized = int(round(row[4]/smallest_box_size))
z2_normalized = int(round(row[5]/smallest_box_size))
editor_cursor.execute("UPDATE boxes SET x1=?,y1=?,z1=?,x2=?,y2=?,z2=? WHERE id=?",(x1_normalized,y1_normalized,z1_normalized,x2_normalized,y2_normalized,z2_normalized,row_id))
其中'最小的盒子大小'只是一些浮动。这是一个简单的规范化任务,基本上每个框坐标必须从其“物理”大小转换为规范化整数坐标。
目前这个过程大约需要几个小时,我想减少这个操作时间。是否可以在我当前的python-SQLite流程中加快这个过程?
有关如何在另一个更快的数据库程序中实现此过程的任何建议也可能有所帮助:)
答案 0 :(得分:3)
让SQLite为您完成所有工作:
editor_cursor.execute("""
UPDATE boxes SET x1=CAST(x1/:smallest_box_size as INTEGER),
y1=CAST(y1/:smallest_box_size as INTEGER),
z1=CAST(z1/:smallest_box_size as INTEGER),
x2=CAST(x2/:smallest_box_size as INTEGER),
y2=CAST(y2/:smallest_box_size as INTEGER),
z2=CAST(z2/:smallest_box_size as INTEGER)""",
{'smallest_box_size': smallest_box_size})
换句话说,SQLite完全能够为您规范化所有行,而无需通过Python管理所有行。
CAST
到INTEGER
已经围绕REAL
值,无需在此处添加明确的round()
来电。
供将来参考:您可以通过迭代光标来遍历结果集。无需为每一行调用.fetchone()
:
cur.execute("SELECT * FROM boxes")
for row in cur:
# loop will terminate automatically when the rows are exhausted.
这是非常有效地实现的,它只加载迭代所需的结果。