2014-12-22 54 views
0

如果X類型是numpy.arrayD型= 'F4'numpy.array的內存分配copy = False?

那麼什麼是線下的內存行爲:

X = array(X, dtype=double, copy=False, order='C', subok=True) 

是否分配新的內存空間爲X(內存使用情況* 2)?

回答

3

NumPy doc有這樣說的copy參數的構造函數array

如果爲true(默認值),則該對象被複制。否則,僅在數組返回副本,如果obj是嵌套序列,或者需要副本以滿足任何其他要求(dtype,order等)時纔會進行復制。

您提供了「其他要求」dtype之一的示例。所以答案是,在這種情況下,copy=False被忽略,因爲要複製必須才能將float32內容轉換爲更高的精度。

+1

這可以通過前後查看'X.flags'來驗證。 – hpaulj

+1

@ frank128791我認爲這是任何系統的默認設置,但是OP指定數組的起始'dtype'是''f4'',它的同義詞是''float32''。 – jez

1

我喜歡運行一些小實驗,看看我的系統中發生了什麼「真的」。這裏有一個簡單的腳本:

import numpy as np 
import numpy.random as rand 
@profile 
def test_size(N=20e6): 
    x = np.zeros(N, dtype=np.float32) 
    x[0] = 200 
    x[N-1] = 123.555 
    x[0:N] = rand.rand(N) 
    x = np.array(x, copy=False, dtype=np.double, order='C', subok=True) 
    x[0:N] = rand.rand(N) 
    y = np.zeros(N, dtype=np.float32) 
    y[0] = 500.0 
    y[1000] = 123.4 
    y[0:N] = rand.rand(N) 
    del(x) 
    del(y) 

    if __name__ == '__main__': 
     test_size() 

和輸出時python -m memory_profiler ./testProc.py分析是:

Line # Mem usage Increment Line Contents 
================================================ 
    3 17.699 MiB 0.000 MiB @profile 
    4        def test_size(N=20e6): 
    5 17.707 MiB 0.008 MiB  x = np.zeros(N, dtype=np.float32) 
    6 17.711 MiB 0.004 MiB  x[0] = 200 
    7 17.719 MiB 0.008 MiB  x[N-1] = 123.555 
    8 94.031 MiB 76.312 MiB  x[0:N] = rand.rand(N) 
    9 170.332 MiB 76.301 MiB  x = np.array(x, copy=False, dtype=np.double, order='C', subok=True) 
    10 170.340 MiB 0.008 MiB  x[0:N] = rand.rand(N) 
    11 170.344 MiB 0.004 MiB  y = np.zeros(N, dtype=np.float32) 
    12 170.344 MiB 0.000 MiB  y[0] = 500.0 
    13 170.344 MiB 0.000 MiB  y[1000] = 123.4 
    14 246.164 MiB 75.820 MiB  y[0:N] = rand.rand(N) 
    15 93.582 MiB -152.582 MiB  del(x) 
    16 17.285 MiB -76.297 MiB  del(y) 

喬指出,內存設置的結果看起來令人驚訝。分析器顯示每行之後的內存分配情況。內存佔用空間在填充陣列的行之後擴大,並在刪除時收縮。在shell上運行ps的結果給出了類似的結果。

進程的已刪除內存是否實際返回到系統堆棧是另一回事。

+0

分析器出錯了。爲'x' _is_分配的內存調用'zeros'(對於20e6 float32's應該〜76MB),並且當你調用'np.array(x,copy = False,dtype = np.double)'時,由於dtype的不同(float32不是float64)。 –

+0

@JoeKington:是的,內存已分配,但這並不一定意味着進程足跡會立即擴展。我已經擴展到這個例子來展示內存佔用情況如何表現。我認爲這是一個合理的畫面,它顯示了對系統的影響。 –

+0

是的,這就是爲什麼逐行內存變化與任何事情無關。這非常具有誤導性。例如,儘管'rand.rand(N)'在將它們分配給'x'之前創建了一個全新的浮點數組,所以結果顯示第10行沒有內存變化。 (第8行和第10行完全等同於'temp = np.random.rand(N); x [:] = temp'。) –