我嘗試運行代碼的Python NumPy的內存佈局
import numpy as np
a = np.zeros((3,2))
b = a.T.reshape(3*2)
b[0] = 99
a
array([[0,0],
[0,0],
[0,0]])
這裏的問題是,在numpy的的重塑函數返回原始數組的一個觀點,如果任何改變發生在視圖對象或主要對象將貫穿整個觀點和主要目標。
但在上述情況下,它不會發生。請解釋。
我嘗試運行代碼的Python NumPy的內存佈局
import numpy as np
a = np.zeros((3,2))
b = a.T.reshape(3*2)
b[0] = 99
a
array([[0,0],
[0,0],
[0,0]])
這裏的問題是,在numpy的的重塑函數返回原始數組的一個觀點,如果任何改變發生在視圖對象或主要對象將貫穿整個觀點和主要目標。
但在上述情況下,它不會發生。請解釋。
的official document給出了一個回答你的問題。
這將是可能的話新的查看對象;否則,它將成爲副本。請注意,不保證返回數組的內存佈局(C-或Fortran-連續)。
你正在做最後的重塑不能在原來的內存佈局的進步表示:
orig 1 2 3 4 5 6 ok, strides 2, 1
transpose 1 3 5 2 4 6 ok, strides 1, 2
reshaped transpose 1 3 5 2 4 6 impossible
我不是100%肯定,我理解這一點正確的(或者,更準確地說,我「M幾乎100%地肯定我沒有),但可能有一些obscure cases當一個副本寫回。無論如何,這不是其中之一。
a = np.array([[1,2],[3,4],[4, 5]]) 然後在給出 陣列([[1,3,4], [2,4,5]]) 然後 aTreshape(3,2)給出 陣列([[1,3 ], [4,2], [4,5]]) 整形發生但沒有完全適當的格式我不明白爲什麼會發生這種情況 – Mayank
我寫的數字並不是指數值,而是指內存位置。內存是線性的,任何多維數組都被劃分爲一組內存地址。爲了保持可管理性,每個維度都有一個_stride_。數組的單元格(2,4)位於內存位置array_base + stride0 x 2 + stride1 x 4.一個新數組通常是C連續的,即最後一個步長爲1,最後一個形狀爲[-1]等等。轉移交換stride0和stride1。 1d數組只有stride0。該示意圖演示了原始佈局不適應扁平轉置的原因。 –
從reshape
文檔
你能想到的整形作爲第一脫散的陣列(使用給定的索引順序),然後使用相同種類的索引的插入從拆紗數組中的元素到新陣列的訂購用於散列
transpose
是一個視圖,但改變形狀,步幅和順序。通過沿着列而不是跨行來獲取原始順序中的元素。但現在嘗試平移轉置 - 按C順序。元素將被洗牌。原始1 2 3 4 5 6 ...變成1 4 7 2 5 8 3 ...您不能在沒有複製的情況下獲得該訂單。
In [48]: a=np.arange(1,7).reshape(3,2)
In [49]: a
Out[49]:
array([[1, 2],
[3, 4],
[5, 6]])
arange
產生[1,2,3....]
。這些數據緩存仍用於a
,您可以通過跨行閱讀「恢復」它。
In [50]: b = a.T
In [51]: b
Out[51]:
array([[1, 3, 5],
[2, 4, 6]])
移調通過改變形狀,進展和順序生成。現在是訂單='F'。 (我可以.flags
和.__array_interface__
表明這一點。這是一個觀點,並且仍然共享原始arange
值。只是現在,因爲進步和秩序的,你讀下來列。
In [52]: c = b.reshape(3,2)
In [53]: c
Out[53]:
array([[1, 3],
[5, 2],
[4, 6]])
這有相同的形狀,長足的進步,和「C」順序a
,但數據緩衝區是原[1,3,5,2..]
重新排序的副本。這是相同的順序,你會從b
通過跨行閱讀得到。
另一種方式來看待在c
的重新排序是跟蹤原始元素順序1,2,3 ...
[0,0],[1,1],[0,1],[2,0],[1,0],[2,1]
或用2名索引列表:
In [57]: a[[0,0,1,1,2,2],[0,1,0,1,0,1]] # regular pattern
Out[57]: array([1, 2, 3, 4, 5, 6])
In [58]: b[[0,1,0,1,0,1],[0,0,1,1,2,2]] # same, switch order
Out[58]: array([1, 2, 3, 4, 5, 6])
In [59]: c[[0,1,0,2,1,2],[0,1,1,0,0,1]] # a jumble
Out[59]: array([1, 2, 3, 4, 5, 6])
如果它創建它的一個觀點,然後np.may_share_memory應返回true,但在我的問題的情況下,它返回false我不知道爲什麼但是如果在重塑函數中,而不是象(3 * 2)那樣寫入,如果你寫(3,2)np.may_share_memory函數返回true。我不是很確定,但是我猜測有一些與3 * 2相關的東西可以複製它我猜 – Mayank