2013-04-10 78 views
2

我有一個大的ASCII文件(〜100GB),其中包含大約1.000.000行已知格式的數字,我嘗試使用python 。該文件是太大,無法讀取完全到內存中,所以我決定用線來處理文件行:什麼是最快的方式在Python中轉換字符串格式化數字在一個numpy陣列

fp = open(file_name) 
for count,line in enumerate(fp): 
    data = np.array(line.split(),dtype=np.float) 
    #do stuff 
fp.close() 

事實證明,我花費在data =行我大部分的程序的運行時間。有什麼方法來加速這條線?另外,執行速度似乎比我從原生FORTRAN程序的格式化讀取要慢得多(請參閱此question,我實現了FORTRAN字符串處理器並將其與f2py一起使用,但運行時間僅與data =我猜想Python/FORTRAN之間的I/O處理和類型轉換會導致我從FORTRAN中獲得的東西被殺死)

因爲我知道格式化,所以不應該有更好更快的方法來使用split()?喜歡的東西:

data = readf(line,'(1000F20.10)') 

我試過fortranformat包,效果不錯,但在我的情況比你split()方法要慢三倍。

P.S.正如EXP和根建議我嘗試了np.fromstring並使它快速dirtry基準:

t1 = time.time() 
for i in range(500): 
    data=np.array(line.split(),dtype=np.float) 
t2 = time.time()  
print (t2-t1)/500 
print data.shape 
print data[0] 
0.00160977363586 
(9002,) 
0.0015162509 

和:

t1 = time.time() 
for i in range(500):  
    data = np.fromstring(line,sep=' ',dtype=np.float,count=9002) 
t2 = time.time() 
print (t2-t1)/500 
print data.shape 
print data[0] 
0.00159792804718 
(9002,) 
0.0015162509 

所以fromstring其實是在我的情況稍微慢一些。

+0

您應該查看用於測試這些小片段的[timeit](http://docs.python.org/2/library/timeit.html)模塊。 – DSM 2013-04-10 10:08:48

回答

1

np.genfromtxt函數是一個速度冠軍,如果你能得到它匹配你的輸入格式。

如果沒有,那麼你可能已經在使用最快的方法。逐行分割數組方法與SciPy Cookbook examples完全匹配。

+0

根據我的理解,'np.genfromtext'會嘗試將整個文件讀入內存,在這種情況下不可能(文件大約100GB)。 – Andre 2013-04-10 08:29:52

+0

如果這是最快的方法,那將會很難過。我不喜歡花費太多時間和CPU週期來處理那些在我看來應該是快速和直接的東西(即使用已知的格式代碼) - 但也許我受到FORTRAN的太多影響。 – Andre 2013-04-10 08:41:21

+0

@Andre不需要將整個文件讀入內存。你也可以使用'fname'作爲一個生成器,它可以從一個簡單的while循環中產生每行的行數。 – 2018-01-30 23:57:42

2

你試過numpyp.fromstring

np.fromstring(line, dtype=np.float, sep=" ") 
+0

是的,速度與split()方法大致相同。我想要真的加速格式代碼必須「本地」使用。 – Andre 2013-04-10 08:35:17

+0

@安德烈 - 對我來說,它比你的「分裂」方法快3倍... – root 2013-04-10 08:38:46

+0

@root好的我會再試一次,也許我錯過了一些東西 – Andre 2013-04-10 08:45:40

相關問題