2017-08-16 53 views
3

我想了解如何最好地利用numpy數組的C順序來編寫高性能代碼。我的期望是,遍歷行的操作應該比遍歷列的操作更快。事實上,這是真的,因爲我嘗試的第一個例子:dtype如何影響Numpy中的行和列操作速度?

X = np.ones((10000,10000),dtype='int64') 
print(X.dtype) 
print(X.flags) 

%timeit np.sum(X,axis=0) 

%timeit np.sum(X,axis=1) 

這將產生輸出:

int64 
    C_CONTIGUOUS : True 
    F_CONTIGUOUS : False 
    OWNDATA : True 
    WRITEABLE : True 
    ALIGNED : True 
    UPDATEIFCOPY : False 
10 loops, best of 3: 79.6 ms per loop 
10 loops, best of 3: 61.1 ms per loop 

這是我所期待的,因爲沿行總結應該比沿着列求和更快。

這裏是我非常困惑的地方。如果我改變了D型到float64,則列操作變得幾乎快兩倍行操作:

X = np.ones((10000,10000),dtype='float') 
print(X.dtype) 
print(X.flags) 

%timeit np.sum(X,axis=0) 

%timeit np.sum(X,axis=1) 

生成輸出:

float64 
    C_CONTIGUOUS : True 
    F_CONTIGUOUS : False 
    OWNDATA : True 
    WRITEABLE : True 
    ALIGNED : True 
    UPDATEIFCOPY : False 
10 loops, best of 3: 67.7 ms per loop 
10 loops, best of 3: 123 ms per loop 

是否有人可以解釋,爲什麼發生這種情況?

編輯:在評論中建議我再試一次較小的矩陣(1000,1000)。當我運行:

import time 
import numpy as np 

X = np.ones((1000,1000),dtype='float') 
print(X.dtype) 
print(X.flags) 

%timeit np.sum(X,axis=0) 
%timeit np.sum(X,axis=1) 

X = np.ones((1000,1000),dtype='int64') 
print(X.dtype) 
print(X.flags) 

%timeit np.sum(X,axis=0) 
%timeit np.sum(X,axis=1) 

我得到的輸出:

float64 
    C_CONTIGUOUS : True 
    F_CONTIGUOUS : False 
    OWNDATA : True 
    WRITEABLE : True 
    ALIGNED : True 
    UPDATEIFCOPY : False 
1000 loops, best of 3: 598 µs per loop 
1000 loops, best of 3: 1.06 ms per loop 
int64 
    C_CONTIGUOUS : True 
    F_CONTIGUOUS : False 
    OWNDATA : True 
    WRITEABLE : True 
    ALIGNED : True 
    UPDATEIFCOPY : False 
1000 loops, best of 3: 788 µs per loop 
1000 loops, best of 3: 632 µs per loop 

所以效果持久。

+0

你有什麼'numpy'和'python'版本? –

+0

@DanielF Python 3.6,Numpy 1.11.3。 – jmracek

+0

嘗試減小'X'的大小(即'(1000,1000)'),並查看在某個時間點的時間差是否從〜200%跳到〜110%。你可能會緩存。 –

回答

1

我無法證實你在OSX(不同的Python版本)第二個結果 - 這類似於你的第一個結果:

In [27]: X = np.ones((10000,10000),dtype='float64') 
    ...: print(X.dtype) 
    ...: print(X.flags) 
    ...: 
    ...: %timeit np.sum(X,axis=0) 
    ...: 
    ...: %timeit np.sum(X,axis=1) 
    ...: 
float64 
    C_CONTIGUOUS : True 
    F_CONTIGUOUS : False 
    OWNDATA : True 
    WRITEABLE : True 
    ALIGNED : True 
    UPDATEIFCOPY : False 
10 loops, best of 3: 67.6 ms per loop 
10 loops, best of 3: 62 ms per loop 

編輯:我多次直接timeit.repeat()您所有的計算:

import timeit 
t = timeit.repeat('np.sum(X,axis=0)', setup="import numpy as np; X = np.ones((10000,10000),dtype='float64')", repeat=50, number=1); print(min(t)); 
t = timeit.repeat('np.sum(X,axis=1)', setup="import numpy as np; X = np.ones((10000,10000),dtype='float64')", repeat=50, number=1); print(min(t)); 
t = timeit.repeat('np.sum(X,axis=0)', setup="import numpy as np; X = np.ones((10000,10000),dtype='int64')", repeat=50, number=1); print(min(t)); 
t = timeit.repeat('np.sum(X,axis=1)', setup="import numpy as np; X = np.ones((10000,10000),dtype='int64')", repeat=50, number=1); print(min(t)); 

with these timing:

Python 2.7.13 |Continuum Analytics, Inc.| (default, Dec 20 2016, 23:05:08) 
IPython 5.3.0 -- An enhanced Interactive Python. 
numpy 1.12.1 

0.0637669563293 # float64, axis=0 
0.0558688640594 # float64, axis=1 
0.0669782161713 # int64, axis=0 
0.0576930046082 # int64, axis=1 

and

Python 3.6.2 |Continuum Analytics, Inc.| (default, Jul 20 2017, 13:14:59) 
IPython 6.1.0 -- An enhanced Interactive Python. Type '?' for help. 
numpy 1.13.1 

0.06289491400821134 
0.05558946297969669 
0.0670205659698695 
0.057950171001721174 

Python 3.5.3 |Continuum Analytics, Inc.| (default, Mar 6 2017, 12:15:08) 
IPython 5.3.0 -- An enhanced Interactive Python. 
numpy 1.11.3 

0.06345970398979262 
0.05561513203429058 
0.07043616304872558 
0.057934076990932226 

最後,我的Android手機上:

Python 3.6.2 (default, Jul 19 2017, 11:01:41) 
IPython 6.1.0 
numpy 1.12.0 

0.39130385394673795 
0.24979593697935343 
0.42852322908584028 
0.28863119706511497 

和Windows系統(蟒蛇3.4 32位):

0.158213707338 
0.149441164907 
0.365552662475 
0.128456460354 
+0

嗯......好的,我必須在另一臺電腦上運行這段代碼。這很奇怪,因爲我能夠在我的機器上重現這個結果。 – jmracek

+0

我在我的機器@jmracek上覆制了它。也許是版本或硬件差異。你運行AGN的版本是'numpy'和'python'嗎? –

+0

我在Microsoft Surface Pro 3上運行python 3.6和numpy 1.11.3。 – jmracek