- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在用 Python 编写一个脚本来对专有 ESRI 数据库表中的 QC 数据进行处理。该脚本的目的不是修改无效数据,而只是通过csv文件向用户报告无效数据。我正在使用 ESRI 的 ArcPy 包通过 arcpy.SearchCursor 访问每个单独的记录。 SearchCursor 是访问 ESRI 格式的每个单独记录的唯一方法。
当我滚动浏览表格的每条记录时,我会进行多次 QC 检查以验证特定的业务逻辑。其中一项检查是在特定字段中查找重复数据。这些领域之一可能是几何学。我通过为每个字段创建一个空容器对象来完成此操作,并在检查每条记录时使用以下逻辑。
for field in dupCheckFields:
if row.getValue(field) in fieldValues[field]: dupValues.add(row.getValue(idField))
else: fieldValues[field].append(row.getValue(field))
上面的代码是我使用的基本逻辑的一个例子。我遇到麻烦的地方是,这些表中的每一个都可能包含 5000 条记录到 1000 万条记录。我要么内存不足,要么性能停止。
我尝试过以下容器类型:集合、列表、字典、ZODB + BList 和 Shelve。
对于内存中的类型(集合、列表、字典),这个过程在开始时非常快,但随着它的进行,它会变得更慢。我们这些类型,如果我在表中有很多记录,我将耗尽内存。使用持久数据类型,我不会耗尽内存,但需要很长时间来处理。
我只在脚本运行时需要数据,所有持久数据文件将在完成后删除。
问题:是否有更好的容器类型来提供大量数据的低内存存储,而访问数据时不会产生大量性能成本?
系统:Win7 64位,Python 2.6.5 32位,4GB内存
预先感谢您的帮助。
编辑:
示例 SQLite 代码:
import sqlite3, os, arcpy, timeit
fc = r"path\to\feature\class"
# test feature class was in ESRI ArcSDE format and contained "." characters separating database name, owner, and feature class name
fcName = fc.split(".")[-1]
# convert ESRI data types to SQLite data types
dataTypes = {"String":"text","Guid":"text","Double":"real","SmallInteger":"integer"}
fields = [(field.name,dataTypes[field.type]) for field in arcpy.ListFields(fc) if field.name != arcpy.Describe(fc).OIDFieldName]
# SQL string to create table in SQLite with same schema as feature class
createTableString = """create table %s(%s,primary key(%s))""" % (fcName,",\n".join('%s %s' % field for field in fields),fields[0][0])
# SQL string to insert data into SQLite table
insertString = """insert into %s values(%s)""" % (fcName, ",".join(["?" for i in xrange(len(fields))]))
# location to save SQLite database
loc = r'C:\TEMPORARY_QC_DATA'
def createDB():
conn = sqlite3.connect(os.path.join(loc,'database.db'))
cur = conn.cursor()
cur.execute(createTableString)
conn.commit()
rows = arcpy.SearchCursor(fc)
i = 0
for row in rows:
try:
cur.execute(insertString, [row.getValue(field[0]) for field in fields])
if i % 10000 == 0:
print i, "records"
conn.commit()
i += 1
except sqlite3.IntegrityError: pass
print i, "records"
t1 = timeit.Timer("createDB()","from __main__ import createDB")
print t1.timeit(1)
不幸的是,我无法共享我在这段代码中使用的测试数据,但它是一个 ESRI ArcSDE 地理数据库表,包含大约。 10 个字段和大约。 700 万条记录。
我尝试使用 timeit
来确定这个过程花费了多长时间,但是在处理了 2 个小时之后,只完成了 120,000 条记录。
最佳答案
如果您将散列存储在(压缩的)文件中,您可以流式传输它们以比较散列以查找重复项。流式传输通常对内存的要求非常低——您可以设置所需的缓冲区,例如,每个散列记录一行。权衡通常是时间,特别是如果您添加压缩,但如果您按某些标准对文件进行排序,那么您可能能够遍历未压缩的流以更快地比较记录。
关于Python - 如何构建和访问大量数据而不用尽内存或减慢处理速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7836672/
我想在订阅中捕获异常,但结果不符合预期。 this.userService.isUsernameValid (username) .pipe ( catchError
我是一名优秀的程序员,十分优秀!