排序大的文本文件的流我有一個大的文本文件,我想以塊的形式讀入數據幀的熊貓3逗號分隔值(> 1GB)。數據框的下面是一個例子:如何篩選和在Python
我想通過這個文件進行過濾,而在輸出一個「乾淨」的版本閱讀。我遇到的一個問題是某些時間戳是無序的,但問題通常是非常局部的(通常情況下,打勾是在前或後幾個時隙內亂序)。有沒有什麼方法可以做本地化的「滑動窗口」排序?
而且,我是相當新的Python和學習有關的I/O方法,我不能確定最佳的類/方法用於過濾大的數據文件。 TextIOBase?
排序大的文本文件的流我有一個大的文本文件,我想以塊的形式讀入數據幀的熊貓3逗號分隔值(> 1GB)。數據框的下面是一個例子:如何篩選和在Python
我想通過這個文件進行過濾,而在輸出一個「乾淨」的版本閱讀。我遇到的一個問題是某些時間戳是無序的,但問題通常是非常局部的(通常情況下,打勾是在前或後幾個時隙內亂序)。有沒有什麼方法可以做本地化的「滑動窗口」排序?
而且,我是相當新的Python和學習有關的I/O方法,我不能確定最佳的類/方法用於過濾大的數據文件。 TextIOBase?
這是一個非常有趣的問題,因爲數據的足夠大到不能裝入內存容易。
首先,關於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()
:
僅供參考,這裏是我的版本的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)
我會用iteetools.islice獲得chuc k的數據 – Copperfield
@Copperfield你能更具體嗎?如果你的意思是提取first_window塊時,我想到了這一點,但我認爲避免導入和使用更多基本內置塊通常更加清晰和簡單。 –
是的,我的意思是'first_window'。此外,您目前的方式有引發StopIteration異常的風險,也許對於這個不成問題的用例,但爲什麼在那裏留下一個容易避免的問題? – Copperfield