2017-02-22 68 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