2011-11-30 15 views
4

我知道numpy數組是指針數組。我知道可以在python中定義指針。但我想知道,如果我使變量等於一個numpy向量中的元素,它仍然是一個指針還是它被去引用?有沒有辦法找到或測試這個?將Numpy/Scipy指針複製到本地變量時會發生什麼?

import scipy 
    vec = scipy.randn(10) 
    vecptr = veC# vecptr is a pointer to vec 
    vecval = scipy.copy(vec) # vecval is not a pointer. 

    var = vec[3] # is var pointer or is it copied by value ??? 

    print(type(var)) # returns numpy.float64. does this mean its a 1x1 numpy vec and therefore a pointer ? 

我想問的原因是,我真正想知道的是,下面的代碼會把我的記憶翻倍嗎?我想創建更有意義的變量名我返回的矢量

v = self.viewCoefs[sz][sv][sa] 

    gw = v[0] 
    G0 = v[1] 
    G1 = v[2] 
    G2 = v[3] 
    alpha0 = v[4] 
    alpha1 = v[5] 
    alpha2 = v[6] 
    beta0 = v[7] 
    beta1 = v[8] 
    beta2 = v[9] 
    beta3 = v[10] 
    gamma0 = v[11] 
    gamma1 = v[12] 
    gamma2 = v[12] 
    gamma3 = v[12] 
    gamma4 = v[13] 
    delta0 = v[14] 
    delta1 = v[15] 
    delta2 = v[16] 
    delta3 = v[17] 
    delta4 = v[18] 
    delta5 = v[19] 
    zeta_prime_0 = v[20] 
    zeta_prime_1 = v[21] 
    zeta_prime_2 = v[22] 
    Gamma_prime_0 = v[23] 
    Gamma_prime_1 = v[24] 
    Gamma_prime_2 = v[25] 
    Gamma_prime_3 = v[26] 

因爲我有很多的這些跟隨

p0 = alpha0 + alpha1*scipy.log(bfrac) + alpha2*scipy.log(bfrac)**2 
    p1 = beta0 + beta1*scipy.log(bfrac) + beta2*scipy.log(bfrac)**2 + beta3*scipy.log(bfrac)**3 
    p2 = gamma0 + gamma1*scipy.log(bfrac) + gamma2*scipy.log(bfrac)**2 + gamma3*scipy.log(bfrac)**3 + gamma4*scipy.log(bfrac)**4 
    p3 = delta0 + delta1*scipy.log(bfrac) + delta2*scipy.log(bfrac)**2 + delta3*scipy.log(bfrac)**3 + delta4*scipy.log(bfrac)**4 + delta5*scipy.log(bfrac)**5 

    subSurfRrs = g*(p0*u + p1*u**2 + p2*u**3 + p3*u**4) 
    ## and lots more 

所以我想有意義的變量名稱,而不加倍我的記憶腳印。

好吧,如果我這樣做是正確的解決方案,不能折起來我的記憶是:

v = self.veiwCoefs[sz][sv][sa] 

    gw = v[0:1] 
    G0 = v[1:2] 
    G1 = v[2:1] 
    alpha0 = v[3:4] 
    alpha1 = v[4:5] 
    alpha2 = v[5:6] 
    beta0 = v[6:7] 
    beta1 = v[7:8] 
    beta2 = v[8:9] 
    beta3 = v[9:10] 
    ## etc 

    p0 = alpha0[0] + alpha1*scipy.log(bfrac) + alpha2[0]*scipy.log(bfrac)**2 
    p1 = beta0[0] + beta1[0]*scipy.log(bfrac) + beta2[0]*scipy.log(bfrac)**2 + beta3[0]*scipy.log(bfrac)**3 

    ## etc 
+0

在這種情況下,你真的不需要擔心「加倍」內存使用。它只有27個花車。如果216 bytes的內存使用量對你來說很重要,不要使用python ......前面已經說過,有些情況下numpy數組的單個元素視圖很有用,但這不是其中之一。 –

回答

4

你幾乎擁有它,但這裏是如何創建一個單個元素的觀點:

In [1]: import numpy as np 

In [23]: v = np.arange(10) 

In [24]: a = v[3:4] 

In [25]: a[0] = 100 

In [26]: v 
Out[26]: array([ 0, 1, 2, 100, 4, 5, 6, 7, 8, 9]) 

這裏av第四元件的視圖,所以當改變a更改在v的相應位置。

+0

因此,它是公平地說,如果我做的:GW = V [0] G0 = V [1] G1 = V [2] G2 = V [3] alpha0 = V [4] ALPHA1 = V [5] alpha2 = v [6]等等。我沒有加倍我的記憶使用率?我只是爲我的矢量創建更有用的手柄? – Caustic

+0

@Caustic - 'gw = v [0]'會創建一個元素的副本,而'gw = v [0:1]'會創建一個不是副本的視圖,但更像是該地點的替代標籤在記憶中。 – JoshAdel

+0

好吧,我想我現在明白了。我需要在方括號中使用gw [0],G0 [0],..等。謝謝! – Caustic

1

視圖是非常有用的,使用它們可以幫助節省相當多的內存,但在你的情況下,我不認爲視圖是合適的。雖然視圖不會重用底層數據,但我不會將其稱爲指針。每個視圖是一個獨特的ndarray對象,這意味着它有它自己的特性,例如形狀:

In [4]: a = np.arange(7) 

In [5]: b = a[1:5] 

In [6]: b.shape = (2,2) 

In [7]: b 
Out[7]: 
array([[1, 2], 
     [3, 4]]) 
In [8]: a.shape 
Out[8]: (7,) 

所以當你b = a[0:1],你要創建一個全新的ndarray對象持有一個INT /浮點/ .. 。 管他呢。如果你願意,你有有意義的名稱爲您的陣列中的每個元素,你可能不會得到更有效的比:

v = self.viewCoefs[sz][sv][sa] 

gw = v[0] 
G0 = v[1] 
G1 = v[2] 
G2 = v[3] 
alpha0 = v[4] 
## etc 

話雖這麼說,你應該嘗試看看是否有更好的方式來向量化你的代碼,意思是將你的代碼寫成數組的操作,而不是對數組元素進行操作。例如,你可能會寫:

coefs = np.zeros((5,5)) 
lt = np.tril_indices(5) 
coefs[lt] = self.viewCoefs[sz][sv][sa] 

p = (coefs * scipy.log(bfrac)**[1, 2, 3, 4, 5]).sum(-1) 
subSurfRrs = g*(p*u**[1, 2, 3, 4]).sum() 

使用numpy時,矢量化代碼可以更快。在這種情況下,我們也利用numpy的廣播,我認爲這是非常混亂的,直到我更好地瞭解它,並意識到它可能會有多大用處。

+0

Thanks @Bago,矢量化的代碼是要走的路。在我確信自己的所有係數都是正確的之後。這是我習慣於在Matlab中做事情的方式。保持目前的條款對於調試更加有用。 – Caustic

相關問題