2017-02-22 60 views
4

排序大的文本文件的流我有一个大的文本文件,我想以块的形式读入数据帧的熊猫3逗号分隔值(> 1GB)。数据框的下面是一个例子:如何筛选和在Python

output

我想通过这个文件进行过滤,而在输出一个“干净”的版本阅读。我遇到的一个问题是某些时间戳是无序的,但问题通常是非常局部的(通常情况下,打勾是在前或后几个时隙内乱序)。有没有什么方法可以做本地化的“滑动窗口”排序?

而且,我是相当新的Python和学习有关的I/O方法,我不能确定最佳的类/方法用于过滤大的数据文件。 TextIOBase?

回答

2

这是一个非常有趣的问题,因为数据的足够大到不能装入内存容易。

首先,关于I/O:如果它是一个CSV我会使用一个标准库csv.reader()对象,像这样(我假设的Python 3):

with open('big.csv', newline='') as f: 
    for row in csv.reader(f): 
     ... 

然后我可能会根据您的描述,将窗口大小设置为可能为20的实例的一个collections.deque(maxlen=WINDOW_SIZE)实例中的行的滑动窗口保持不变。阅读第一WINDOW_SIZE行到双端队列,然后进入主读取环路将输出的双端队列最左边的项目(行),然后追加当前行。

在追加每行之后,如果当前行的时间戳记位于前一行(window[-2])的时间戳记的前面,那么对排序进行排序。你不能一个deque直接进行排序,但这样做:

window = collections.deque(sorted(window), maxlen=WINDOW_SIZE) 

Python的Timsort算法手柄已经排序的运行效率,所以这应该是非常快的(线性时间)。

如果窗口大小和乱序行数很小(听起来他们可以),我相信整体算法将是O(N),其中N是行中的行数数据文件,所以线性时间。

更新:我写了一些演示代码来生成这样一个文件,然后用以上方法对其进行排序 - 见this Gist,Python的3.5测试。它比sort工具在相同的数据快得多,也快于Python的sorted()功能约ñ= 1,000,000之后。顺便提一句,生成演示CSV的函数比排序代码慢得多。 :-)我的结果关于各种N(肯定看起来线性ISH)定时process_sliding()

  • N = 1000000:3.5s的
  • N = 2000000:6.6s
  • N = 10,000,000:32.9s

仅供参考,这里是我的版本的process_sliding()代码:

def process_sliding(in_filename, out_filename, window_size=20): 
    with (open(in_filename, newline='') as fin, 
      open(out_filename, 'w', newline='') as fout): 
     reader = csv.reader(fin) 
     writer = csv.writer(fout) 

     first_window = sorted(next(reader) for _ in range(window_size)) 
     window = collections.deque(first_window, maxlen=window_size) 

     for row in reader: 
      writer.writerow(window.popleft()) 
      window.append(row) 
      if row[0] < window[-2][0]: 
       window = collections.deque(sorted(window), maxlen=window_size) 

     for row in window: 
      writer.writerow(row) 
+0

我会用iteetools.islice获得chuc k的数据 – Copperfield

+0

@Copperfield你能更具体吗?如果你的意思是提取first_window块时,我想到了这一点,但我认为避免导入和使用更多基本内置块通常更加清晰和简单。 –

+0

是的,我的意思是'first_window'。此外,您目前的方式有引发StopIteration异常的风险,也许对于这个不成问题的用例,但为什么在那里留下一个容易避免的问题? – Copperfield