2016-04-29 73 views
0

我有一個數以百萬計的項目在一個相當慢的磁盤上的目錄。我想隨機抽取100個這樣的項目,我也想用glob來做。在Python中隨機抽取目錄的最有效方法

一種方式做到這一點是讓目錄中每個文件的水珠,然後將樣品是:

files = sorted(glob.glob('*.xml')) 
file_count = len(files) 
random_files = random.sample(
    range(0, file_count), 
    100 
) 

但這實在是太慢了,因爲我要建立的數百萬個文件的大名單,它必須做大量的磁盤抓取。

有沒有更快的方法來做到這一點,而不是打擊磁盤?它不一定是一個完美分佈的樣本,或者甚至只有100個項目,只要速度快。

我在想:

  • 也許我們可以使用索引節點要快?
  • 也許我們可以在不知道磁盤上的全部內容的情況下選擇項目?
  • 也許有一些捷徑可以使這個更快。
+0

是否目錄的變化,往往?如果沒有,則將文件列表存儲在另一個文件中,並將其用於隨機抽樣。 –

+0

@BrentWashburne它並沒有改變,但我寧願避免混亂,如果技術解決方案是可能的。 – mlissner

+0

文件名是否遵循一種模式?如果第一個字符是[a-z]中的一個字母,那麼您可以選擇一個隨機字母來啓動該glob並隨機選擇一個字母。重複100個文件。 –

回答

0

使用os.listdir代替glob。這是這個速度的兩倍。

import glob, random, os, time 

n, t = 0, time.time() 
files = sorted(glob.glob('tmp/*')) 
file_count = len(files) 
print(file_count) 
random_files = random.sample(range(0, file_count), 100) 
t = time.time() - t 
print "glob.glob: %.4fs, %d files found" % (t, file_count) 

n, t = 0, time.time() 
files = sorted(os.listdir("tmp/")) 
file_count = len(files) 
print(file_count) 
random_files = random.sample(range(0, file_count), 100) 
t = time.time() - t 
print "os.listdir: %.4fs, %d files found" % (t, file_count) 

輸出

glob.glob: 0.6782s, 124729 files found 
os.listdir: 0.3183s, 124778 files found 

注意,如果有關於該文件的名稱,它會讓你隨機生成他們將要走的路的一些信息。或者,如果您可以將這些文件重新命名爲適合隨機採樣的格式,那麼也可以使用。

+0

謝謝,我會看看這個,但我確實需要globbing,這可能會在'listdir'中增加一些開銷。 – mlissner

0

也許我們可以使用inode更快?

沒有索引節點,但目錄條目,你不要;不想叫 stat()上的每個文件

也許我們可以選擇的項目不知道的磁盤上有什麼整體?

是的,這是計劃。打開目錄,讀取目錄條目,樣本100出來億,然後纔得到這些文件

在C,這將是opendir()/readdir()電話

在Python中類似的調用由scandir執行,這應包括在Python 3.5 RTL。如果不是,從https://github.com/benhoyt/scandir

UPDATE

鏈接讓它OpenGroup的文檔WRT opendir()/readdir()http://pubs.opengroup.org/onlinepubs/009695399/functions/opendir.html

相關問題