【问题标题】:What is the most efficient way to repeatedly search a large text file (800 MB) for certain numbers?重复搜索大型文本文件(800 MB)以查找某些数字的最有效方法是什么?
【发布时间】:2019-07-20 06:56:44
【问题描述】:

大文件是 1200 万行文本,例如:

81.70,  89.86,  717.985
81.74,  89.86,  717.995
81.78,  89.86,  718.004
81.82,  89.86,  718.014
81.86,  89.86,  718.024
81.90,  89.86,  718.034

这是纬度、经度和与最近海岸线的距离(分别)。

我的代码使用已知地点的坐标(例如:墨西哥城:“-99.1, 19.4)并逐行搜索大文件,以输出与该坐标最近的海岸线的距离。

我将每一行放入一个列表中,因为很多行都符合长/纬度标准。我后来平均了到海岸线的距离。

检索每个坐标大约需要 12 秒。我的整个脚本需要 14 分钟才能完成。

这是我一直在使用的:

long = -99.1
lat = 19.4
country_d2s = []

# outputs all list items with specified long and lat values
with open(r"C:\Users\jason\OneDrive\Desktop\s1186prXbF0O", 'r') as dist2sea:
    for line in dist2sea:
        if long in line and lat in line and line.startswith(long):
             country_d2s.append(line)

我正在寻找一种方法来更快地搜索文件和/或重写文件以使其更易于使用。

【问题讨论】:

  • 您的脚本只是无法工作,因为line 是一个字符串,而 lat & long 是浮点数。先转换为浮点数列表,然后进行测试。
  • 您是否可以选择将文件拆分为具有有意义名称的较小文件?即,您可以有一个名为 81.70 的文件,其中包含该纬度的所有坐标,或者可能有一个名为 81 的文件,其中包含所有 81.* 纬度。
  • @Jean-FrançoisFabre 我想这是他真实代码的简化版本。
  • 要获得优化的解决方案,应该回答一些额外的问题:坐标看起来是有序的,是吗?坐标看起来以恒定频率(0.04)采样,是吗? lat 值的所有循环是否完全包含在文件中(或者需要某种插值)?顺便说一句,您的匹配标准不是很精确,例如它会匹配-99.1, 89.86, 719.424,因为19.4 是距离的子字符串。
  • 文件中数据的顺序重要吗?你会用它做其他事情吗?

标签: python large-files writetofile


【解决方案1】:

使用具有由纬度和经度组成的键的数据库。如果您正在寻找可以作为文件共享的轻量级数据库,可以使用SqliteDictbsddb3。这比每次运行程序时读取文本文件要快得多。

【讨论】:

    【解决方案2】:

    将您的数据导入 SQLite 数据库,然后为 (latitude, longitude) 创建索引。索引查找应该花费几毫秒。要读取数据,请使用 python SQLite 模块。

    【讨论】:

      【解决方案3】:

      评论:

      • 目前尚不清楚您是否使用了您的经纬度为 XX.Y 的事实,并且您正在搜索 XX.YY 作为某种模糊匹配技术。
      • 我也不知道您打算如何执行此操作:load + [run] x 1000[load + run] x 1000,这将告知您要使用的解决方案。

      话虽如此,如果您想进行非常快速的精确查找,一种选择是将整个事物作为映射加载到内存中,例如{(long, lat): coast_distance, ...}。由于浮点数不是好键,因此最好使用字符串、整数或分数。

      如果你想做模糊匹配,有一些数据结构(和一些包)可以解决这个问题:

      如果您希望初始加载时间更快,您可以执行诸如编写二进制 pickle 并直接加载它而不是解析文件之类的操作。数据库也是一个简单的解决方案。

      【讨论】:

        【解决方案4】:

        您可以将文件分成 10 x 10 度的补丁。这将减少 648 个搜索空间,这将产生 648 个文件,每个文件大约有 18500 行。这会将搜索时间减少到大约 0.02 秒。

        当您进行经纬度的精确匹配时,您可以改用任何磁盘键值存储。 Python 至少内置了其中一个。如果您要进行最近邻或度量空间搜索,有空间数据库支持这些。

        【讨论】:

          【解决方案5】:

          如果您使用 python,我建议使用 PySpark。 在这种特殊情况下,您可以使用函数 mapPartitions 并加入结果。 这可以帮助How does the pyspark mapPartitions function work?

          PySpark 在处理海量数据时非常有用,因为它可以创建 N 个分区并充分利用您的处理器。

          希望对你有帮助。

          【讨论】:

            猜你喜欢
            • 2012-01-06
            • 2020-11-10
            • 2012-02-12
            • 2019-08-24
            • 2016-10-22
            • 2011-12-06
            • 2015-08-09
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多