2016-10-20 87 views
-1

我們試圖從非常大的文件中獲取大約1M的隨機行,其中可能有大約3M記錄。所選的隨機行需要寫入第三個文件。 您對我們有任何建議嗎?Python - 從一個非常大的文件中讀取隨機行並追加到另一個文件

+1

你想選擇一條沒有偏見的線嗎?因爲如果沒有,你可以很容易地找到一個隨機的位置,然後找到一個'\ n'。 –

+0

你的第一句話寫得不好,我不明白。 「行」和「記錄」之間的關係是什麼?源文件中有多少行/記錄?你想要在輸出文件中有多少個?行/記錄有多大? –

+0

@FranciscoCouzo這是一個有趣的想法,但也有風險輸出同一行多次,除非你跟蹤你已經找到哪個'\ n'並跳過它們。我認爲這會增加它自己的偏見(如果隨機數字恰好彼此接近,那麼會有所偏差),但是自從我研究了統計數據以來,它已經太長了! – tdelaney

回答

1

您可以使用readlines()並將該文件轉儲到列表中。那麼你可以簡單地生成一百萬個隨機數字。當然,它們必須位於文件列表大小的範圍內,並且每次生成一個隨機數就可以訪問列表中該位置的行,並將其寫入要移動的文件中in。

+0

OP表示這個文件非常大,因爲它將整個文件讀入內存,所以會排除'readlines'。 –

+0

@FranciscoCouzo除非他們是典型的noob,他認爲幾兆字節非常大。多次看過。 –

+0

嘿,我以爲你刪除了你的,所以我寫了我的!無論如何,我同意。 +1等等......我舉了一個例子,所以我認爲我也會保持我的。 – tdelaney

2

3百萬條記錄,比如說100個字符行並不是很大 - 這完全取決於你使用的硬件。你可以這樣做:

import random 

with open('input.txt') as infile, open('output.txt', 'a') as outfile: 
    outfile.writelines(random.sample(infile.readlines(), 1000000)) 

這是一個更快的方法來做到這一點,它的簡單。那麼,這是一個看看它是否適合你的問題。

3

以供將來參考,因爲其他的答案已經給了,對於適合在內存的工作負載工作的解決方案:

import random 

def reservoir_sampling(l, k): 
    it = iter(l) 
    try: 
     result = [next(it) for _ in range(k)] # use xrange if on python 2.x 
    except StopIteration: 
     raise ValueError("Sample larger than population") 

    for i, item in enumerate(it, start=k): 
     s = random.randint(0, i) 
     if s < k: 
      result[s] = item 

    random.shuffle(result) 
    return result 

with open('input.txt') as infile, open('output.txt', 'a') as outfile: 
    for line in reservoir_sampling(infile, 1000000): 
     outfile.write(line) 

的算法稱爲水庫取樣,並且需要O(n)時間和O(k)內存,這取決於你需要你可能需要也可能不需要撥打random.shuffle

+0

它看起來複雜而有趣,但最終你只是讀第一個_k_文件行(單字母標識符?!)並對它們進行洗牌。不是OP的意圖。 – volcano

+2

@volcano你是怎麼錯過算法的整個中間部分的? –

+0

@StefanPochmann,你是如何錯過文件迭代器上的_next_將從文件中讀取一行的?我確信它會,但我仍然對它進行測試。瞧 - 懷疑證實。 沒有magic-line *結果= [next(it)for _ in xrange(k)] *將首先讀取_k_行到列表中 - 這樣0k承諾也是錯誤的。 – volcano

相關問題