【发布时间】:2016-06-26 21:20:44
【问题描述】:
我们有一个包含大约 4600 万条 CSV 格式记录的文件。每条记录大约有 18 个字段,其中一个是 64 字节的 ID。我们有另一个文件,其中包含大约 167K 的唯一 ID。与 ID 对应的记录需要被拉出。因此,我们编写了一个 python 程序,它将 167K ID 读取到一个数组中,并处理 4600 万条记录文件,检查 ID 是否存在于每条记录中。这是代码的sn-p:
import csv
...
csvReadHandler = csv.reader(inputFile, delimiter=chr(1))
csvWriteHandler = csv.writer(outputFile, delimiter=chr(1), lineterminator='\n')
for fieldAry in csvReadHandler:
lineCounts['orig'] += 1
if fieldAry[CUSTOMER_ID] not in idArray:
csvWriteHandler.writerow(fieldAry)
lineCounts['mod'] += 1
在一小部分数据上测试了程序,这里是处理时间:
lines: 117929 process time: 236.388447046 sec
lines: 145390 process time: 277.075321913 sec
我们已经在昨晚 3:00am EST 开始在 4600 万条记录文件(大约 13GB 大小)上运行程序,现在大约是 10am EST,它仍在处理中!
问题:
- 是否有更好的方法来处理这些记录以缩短处理时间?
- python 是正确的选择吗? awk 或其他工具会有所帮助吗?
- 我猜测在以下语句中查找 167K 数组的 64 字节 ID 是罪魁祸首:
if fieldAry[CUSTOMER_ID] not in idArray:
有更好的选择吗?
谢谢!
更新:这是在带有 EBS 附加卷的 EC2 实例上处理的。
【问题讨论】:
-
idArray的类型是什么?确保它是一些支持有效成员资格测试的数据结构,例如set可能会比普通的[]列表快很多。 -
如何使用数据库管理系统...
-
1) “将 167K ID 读入一个数组” ...如果我理解正确,您的意思是列表?尝试使用 set(); 2) 为 ineCounts['orig'] 和 lineCounts['mod'] 创建 tmp 变量,在循环后将它们分配回去; 3)不确定csv.reader是如何实现的,如果yield(for row in it)产生IO操作,也许你可以先把CSV读入内存..
-
这个很棘手,我已经回答了一个类似的问题,在这种情况下,用户需要检查大量数据集的时间戳(每行的开头)。我会问你同样的问题,是否有可能在数据库替代方案中获取 4500 万条记录?
-
@FrerichRaabe idArray 是一个包含 64 字节 ID 的数组,大小约为 167K。我们将根据数组检查集合。 -谢谢
标签: python arrays csv lookup latency