【问题标题】:Python : The most efficient way to join two very big (20+ GB) datasets?Python:加入两个非常大(20+ GB)数据集的最有效方法?
【发布时间】:2015-08-23 05:01:33
【问题描述】:

我有一个 21 GB 的数据集 df_ns:

domain|ns
123.com|ns1.domanihost.com
hymi.net|ns2.hostinger.com

还有另一个 12 GB 数据集 df_ip:

ip|domain
28.76.2.2|myname.com
86.90.234.5| 123.com

我想加入他们的域名,并为两个文件中的域提取 ip 和 ns。

我想到的使用方式是将 df_ip 数据加载到字典中,并逐行遍历 df_ns 数据并检查域是否存在,然后提取 ns.但它仍然非常消耗资源。

还有其他更有效的方法吗?

【问题讨论】:

  • StringIO怎么样?
  • 您对非 Python 解决方案持开放态度吗?这是一个有效的解决方案:sort -o df_ns.csv df_ns.csv && sort -o df_ip.csv df_ip.csv && join -t'|' df_ns.csv df_ip.csv > df_combined.csv
  • @Robᵩ 你能把它作为答案发布吗?

标签: python join dictionary lookup


【解决方案1】:

按第一列对数据进行排序,例如,使用 gnu 排序。 之后,您不需要将数据存储在内存中,只需使用两个迭代器,如下所示:

import csv, sys
it1 = (csv.reader(open("df_ns", "r")))
it2 = (csv.reader(open("df_ip", "r")))
# skip the headers
it1.next()
it2.next()
try:
    dm1, ns = it1.next() # first row
except StopIteration:
    sys.exit(0)
try:
    dm2, ip = it2.next()
except StopIteration:
    sys.exit(0)
while True:
    if dm1 == dm2:
        print dm1, ns, ip
    if dm1 < dm2:
        try:
            dm1, ns = it1.next()
        except StopIteration:
            break
        continue
    try: 
        dm2, ip = it2.next()
    except StopIteration:
        break

【讨论】:

  • 感谢您的帮助。由于 it1 和 2 是列表,因此不能将它们分配给 dm1,ns 之类的两个值。您还有其他想法吗?
  • 不客气。 It1 和 2 实际上不是列表,它们必须是产生元组的迭代器。为什么要将它们分配两个值?
  • 我不想要它。但目前我收到了一个价值太大的错误,无法在您的答案的第一个“try-catch”中解压。
  • 哦,对不起,我没有测试代码——我给出它只是为了说明这个想法。但是如果要解压的值太多,那么这意味着您的 csv 文件可能不是两列逗号分隔的值...请您添加类似 "row = it1.next(); print row; dm1 , ns = it1.next()" 这样我们就可以看到发生了什么?
【解决方案2】:
sort -o df_ns.csv df_ns.csv && \
sort -o df_ip.csv df_ip.csv && \
join -t'|' df_ns.csv df_ip.csv > df_combined.csv

参考:http://linux.die.net/man/1/join

【讨论】:

    猜你喜欢
    • 2016-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-07
    • 2012-09-04
    • 1970-01-01
    • 2019-06-22
    • 1970-01-01
    相关资源
    最近更新 更多