【问题标题】:Python: Iterating Large FilesPython:迭代大文件
【发布时间】:2020-10-16 11:16:04
【问题描述】:

我是一名初学者,我会感谢任何解决我问题的方法。简单地说,我有两个文件,每个文件包含一个向量。目的是从文件 1 中减去文件 2 的所有元素;对于所有可能的组合。小向量一切都很好,一切都很好,但是对于较大的文件,例如每个文件中有数百万个元素,处理时间很长。

下面给出的是最小的工作示例。我听说过内存映射,如果您能分享修改后的版本或任何相关的指针来处理这个问题,我将不胜感激。

import matplotlib.pyplot as plt
import numpy as np

file1 = np.loadtxt('File_1.txt',delimiter=',')
file2 = np.loadtxt('File_2.txt',delimiter=',')
event1 = file1[:,1]
event2 = file2[:,1]

r1 = len(event1)
r2 = len(event2)

diff = []

for i in range(0,r1):

    for j in range(0,r2):
        delta = float(event1[i]-event2[j])

        if delta >=-4000 and delta <=4000:
            diff = np.append(diff, delta)
            

np.savetxt('export.txt', diff)

【问题讨论】:

  • 每个文件中的一百万个元素是 10**12 个组合,如果你只是用蛮力的话。你不能那样做。
  • 如果您能分享一个修改后的版本或任何相关的指针来处理这个问题,我将不胜感激。我认为这是题外话。查看代码,文件 IO 甚至是问题吗?如果您的代码涉及大量迭代和追加,则 NumPy 数组可能不是数据结构的合适选择。你做过剖析吗?请参阅How to Askhelp center
  • 嗨,Christain,是的,我无法找到出路,因为我不是编程专家。将不胜感激任何帮助。谢谢!
  • 好的,我现在要睡觉了,所以我只是给你一个快速提示。如果明天不能解决这个问题,请输入正确的答案。您需要加载一个文件并对其进行排序。然后对于另一个文件中的每个元素,您可以使用二进制搜索来查找适合您的增量的元素范围。这将是 O(n log n),速度要快得多。
  • 您好 AMC,不知道 profiling,现在在 Google 上搜索,您能详细说明一下我可以搜索和学习的关键字吗?

标签: python arrays loops iteration memory-mapped-files


【解决方案1】:

这是一个 O(n log m + number_of_matches) 的解决方案。这仍然可以默认返回 O(n*m),因为可能的输出数量很大(如果所有元素的值都彼此接近)。如果匹配很少,这会更快:

#two pointer approach

event1 = sorted(event1)
event2 = sorted(event2)


diff = []

#smallest 
if len(event1) > len(event2):
    event1, event2 = event2,event1

left  = 0
right = 0
for e in event1:
    # move left pointer so that is within -delta of e
    while left < len(event2) and event2[left] - e < -4000:
        left +=1
    #move right pointer so that is outside of +delta
    while right < len(event2) and event2[right] - e <= 4000:
        right +=1

    for i in range(left,right):
        diff.append(e - event2[i])

在我的机器上测试,这比示例文件快了大约 6 倍。如果 delta 与数字相比(点击次数少)相对较小,则速度会快很多;如果 delta 非常大(点击次数多),则大致相同(甚至更慢)。

【讨论】:

  • 最后一个for循环可以换成diff.append(e - event2[left: right]
  • Christian:非常简洁,我昨天读到了二进制搜索,现在解决方案对我来说很有意义。救生员!
  • Pramote:我尝试了你的建议。但是,使用 np.savetxt('export3.txt', diff) 保存时遇到错误。你知道这里发生了什么吗?在此处查看 error.txt:drive.google.com/drive/folders/…
  • 嗨 Christian,append 方法现在给我一个内存错误,每个文件中的大小 > 百万个事件,你有什么建议吗?
  • 当差异变大并开始一个新表时,您可以经常保存到文件中。 (使用磁盘使内存更小)。
【解决方案2】:

这可能会有所帮助。

import numpy as np
file1 = np.loadtxt('File_1.txt', delimiter=',')
file2 = np.loadtxt('File_2.txt', delimiter=',')
event1 = file1[:, 1]
event2 = file2[:, 1]

diff = []
for item in event2:
    event_delta = event1 - item
    event_delta_filter = list(filter(lambda x: -4000 <= x <= 4000, event_delta))
    diff = np.append(diff, event_delta_filter)

print(diff)

【讨论】:

  • 您好 Pramote,虽然我很感谢您的回复,但我仍然看不到每个文件中的百万个事件的计算时间有太大变化。您还有其他建议吗?
  • 时间复杂度为 O(n*m)。如果向量大小相似,则为 O(n^2)。运行需要时间。您拥有的数据越多,花费的时间就越多。在您的情况下,如果您将数据大小翻倍,则需要四倍的时间。上面的代码尝试使用尽可能多的 NumPy 功能。如果您想要更好的计算性能,您应该将语言切换为 C、C++、C# 或 Java。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多