如何使用Python跳过二进制标准输入的n行?

时间:2019-04-01 21:26:44

标签: python hadoop optimization binaryfiles

我正在使用Hadoop CLI将二进制数据传递到Hadoop集群上的Python脚本。二进制数据具有标识新文档从何处开始的终止符。记录按唯一标识符(从1000000001开始,以1递增)排序。

我正在尝试仅保存字典中具有的这些ID的子集的数据。

我当前的过程是使用以下命令从CLI中选择数据:

hadoop select "Database" "Collection" | cut -d$'\t' -f2 | python script.py

并在script.py中对其进行处理,如下所示:

import json
import sys

member_mapping = json.load(open('member_mapping.json'))

output = []

for line in sys.stdin:
    person = json.loads(line)
    if member_mapping.get(person['personId']):
        output.append({person['personId']: person})
    if len(output) == len(member_mapping):
        break

问题是此二进制数据中有650万个ID,扫描几乎要花2个小时。我知道字典中的min()和max()ID,并且您可以在我的代码中看到保存了n个文档(其中n是映射文件的长度)后我就停止了。

我想通过跳过尽可能多的读取来提高此过程的效率。如果ID以1000000001开始并且我要保存的第一个ID是1000010001,我可以简单地跳过 10,000行吗?

由于系统问题,我目前无法使用spark或任何其他可以改善此过程的工具,因此,我现在必须坚持使用Python和Hadoop CLI的解决方案。

1 个答案:

答案 0 :(得分:0)

您可以尝试使用enumerate和阈值,然后跳过您不在乎的区域中的所有输入。这不是直接的解决方法,但是应该运行得更快,并且可以将前10,000行迅速抛弃。

for lineNum, line in enumerate(sys.stdin):
    if(lineNum < 10000):
         continue
    person = json.loads(line)
    if member_mapping.get(person['personId']):
        output.append({person['personId']: person})
    if len(output) == len(member_mapping):
        break