好的,我不是 numpy 方面的專家,如果答案很明顯,很抱歉,但這已經困擾我好幾天了,所以除了在這里問之外我別無選擇。所以,這是我的輸入陣列:
a = np.array([
[0, 0, 1, 3, 4, 5, 12, 0, 0, 0, 0, 0 ],
[0, 0, 4, 0, 13, 0, 0, 2, 0, 0, 0, 0 ],
[1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0 ],
[5, 4, 9, 0, 3, 0, 7, 2, 0, 0, 0, 0 ],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
[0, 0, 0, 0, 1, 0, 5, 7, 5, 0, 1, 0 ],
[0, 0, 0, 0, 0, 5, 12, 3, 0, 4, 12, 3 ],
[0, 0, 0, 0, 5, 14, 0, 9, 10, 2, 0, 15 ]
])
它需要被分成大小為 4x4 的圖塊(這意味著每個圖塊有 16 個元素,您會明白為什么這很重要)。我將它平鋪(使用 Iosif Doundoulakis 的np.reshape()方法,在此處解釋,大喊大叫):
def tiling(arr):
# 16 - total number of elements getting into a tile
# 4 - width of a tile
# 4 - height of a tile
b = arr.reshape(arr.shape[0] // 4, 4, arr.shape[1] // 4, 4, 1)
return b.swapaxes(1, 2)
...而且,當我打電話時tiles = tiling(a),我得到了類似的結果:
*為了便于閱讀,我對輸出進行了格式化,實際輸出看起來不同,但組織方式相同。
[[
[
[[ 0] [ 0] [ 1] [ 3]]
[[ 0] [ 0] [ 4] [ 0]]
[[ 1] [ 2] [ 3] [ 4]]
[[ 5] [ 4] [ 9] [ 0]]
]
.... this is one tile, there are 5 more ...
]]
這正是我希望我的瓷磚看起來的樣子。然后,我將平鋪陣列展平,所以它變成
[ 0 0 1 3 0 0 4 0 1 2 3 4 5 4 9 0 4 5 12 0 13 0 0 2
5 6 7 8 3 0 7 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 5 7
0 5 12 3 5 14 0 9 0 0 0 0 5 0 1 0 0 4 12 3 10 2 0 15]
每16個數字代表一個瓷磚。下一步是將展平陣列傳遞給一個外部程式,該程式回傳一個具有相同形狀的陣列 - 一維陣列。目前,資料只傳遞給外部實用程式并由它回傳,因此陣列保留它的值。
知道進入瓦片的陣列元素總數 (16) 以及瓦片的形狀 (4, 4),我如何將這個一維陣列重新轉換為瓦片,然后創建一個二維陣列從那些瓷磚上看,哪一個看起來像從一開始的那個?
uj5u.com熱心網友回復:
我認為這實際上就像另一個swapaxes和reshape. 首先,您需要swapaxes(1, 2) 再次呼叫以撤消上一次呼叫。然后只需重塑回a' 形狀。
>>> tiles
array([[[[[ 0],
[ 0],
[ 1],
[ 3]],
[[ 0],
[ 0],
[ 4],
[ 0]],
...
]]])
>>> tiles.swapaxes(1, 2).reshape(a.shape)
array([[ 0, 0, 1, 3, 4, 5, 12, 0, 0, 0, 0, 0],
[ 0, 0, 4, 0, 13, 0, 0, 2, 0, 0, 0, 0],
[ 1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0],
[ 5, 4, 9, 0, 3, 0, 7, 2, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 1, 0, 5, 7, 5, 0, 1, 0],
[ 0, 0, 0, 0, 0, 5, 12, 3, 0, 4, 12, 3],
[ 0, 0, 0, 0, 5, 14, 0, 9, 10, 2, 0, 15]])
如果你沒有a.shape,你可能可以用類似的東西來計算它(S[0]*S[2], S[1]*S[3]),其中S是tiles.shape:
tiles.swapaxes(1, 2).reshape(x.shape[0] * x.shape[2], x.shape[1] * x.shape[3])
uj5u.com熱心網友回復:
Iosif Doundoulakis 方法的好處之一是平鋪陣列和原始陣列共享記憶體。
original_array = np.array([
[0, 0, 1, 3, 4, 5, 12, 0, 0, 0, 0, 0],
[0, 0, 4, 0, 13, 0, 0, 2, 0, 0, 0, 0],
[1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0],
[5, 4, 9, 0, 3, 0, 7, 2, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 5, 7, 5, 0, 1, 0],
[0, 0, 0, 0, 0, 5, 12, 3, 0, 4, 12, 3],
[0, 0, 0, 0, 5, 14, 0, 9, 10, 2, 0, 15],
])
tile_rows, tile_cols = tile_shape = (2, 4)
grid_rows, grid_cols = grid_shape = (original_array.shape[0] // tile_shape[0],
original_array.shape[1] // tile_shape[1])
tiled_array = original_array \
.reshape((grid_rows, tile_rows, grid_cols, tile_cols, 1)) \
.swapaxes(1, 2)
print(np.shares_memory(tiled_array, original_array)) # True
tiled_array是一個視圖original_array;的任何就地修改tiled_array也適用于original_array:
tiled_array[0, 0] = 99
print(original_array)
印刷
[[99 99 99 99 4 5 12 0 0 0 0 0]
[99 99 99 99 13 0 0 2 0 0 0 0]
[ 1 2 3 4 5 6 7 8 0 0 0 0]
[ 5 4 9 0 3 0 7 2 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 1 0 5 7 5 0 1 0]
[ 0 0 0 0 0 5 12 3 0 4 12 3]
[ 0 0 0 0 5 14 0 9 10 2 0 15]]
正如其他人指出的那樣,可以通過將軸交換回來并重新整形來反轉轉換,
recovered_original_array = tiled_array \
.swapaxes(1, 2) \
.reshape((grid_rows * tile_rows, grid_cols * tile_cols))
print(np.all(recovered_original_array == original_array)) # True
這三個陣列都共享記憶體。
print(np.shares_memory(recovered_original_array, original_array)) # True
但是,當您使用該方法展平陣列時,這個有用的屬性會被破壞flatten,因為flatten總是回傳副本而不是視圖,
flat_array = tiled_array.flatten()
print(np.shares_memory(flat_array, original_array)) # False
該reshape方法-1作為其引數呼叫,如果可能,將回傳一個展平視圖,否則將回傳一個副本。在這種情況下,它回傳一個副本。
flat_array = tiled_array.reshape(-1)
print(np.shares_memory(flat_array, original_array)) # False
tiled_array無論哪種方式,您都可以輕松地從中恢復flat_array,
recovered_tiled_array = flat_array.reshape((grid_rows, grid_cols, tile_rows, tile_cols, 1))
print(np.shares_memory(recovered_tiled_array, tiled_array)) # False
print(np.all(recovered_tiled_array == tiled_array)) # True
據我所知,沒有辦法按照您需要的順序制作原始陣列的平面陣列視圖。但是,您可以制作平鋪陣列的平面視圖,然后進行處理。為此,請制作一份tiled_array
tiled_array = original_array \
.reshape((grid_rows, tile_rows, grid_cols, tile_cols, 1)) \
.swapaxes(1, 2).copy()
print(np.shares_memory(tiled_array, original_array)) # False
允許相同的平面視圖,
flat_array = tiled_array.reshape(-1)
print(np.shares_memory(flat_array, tiled_array)) # True
flat_array[:] = function_on_flat_array(flat_array) # changes apply automatically to flat_array
uj5u.com熱心網友回復:
我不明白你到底想要什么,但我想你正在尋找類似我之前的答案的東西(shape = (6, 4 ,4)你的例子):
a.reshape(a.shape[0] // 4, 4, -1, 4).swapaxes(1, 2).reshape(a.size // (4 * 4), 4, 4)
您需要將回傳陣列重塑為a.size // (4 * 4), 4, 4)(如果您確定可以被 4 或 16 整除的形狀……),因此平鋪函式必須更改為:
def tiling(arr):
b = arr.reshape(arr.shape[0] // 4, 4, arr.shape[1] // 4, 4, 1)
return b.swapaxes(1, 2).reshape(arr.size // (4 * 4), 4, 4)
# [[[ 0 0 1 3]
# [ 0 0 4 0]
# [ 1 2 3 4]
# [ 5 4 9 0]]
#
# [[ 4 5 12 0]
# [13 0 0 2]
# [ 5 6 7 8]
# [ 3 0 7 2]]
#
# [[ 0 0 0 0]
# [ 0 0 0 0]
# [ 0 0 0 0]
# [ 0 0 0 0]]
#
# [[ 0 0 0 0]
# [ 0 0 0 0]
# [ 0 0 0 0]
# [ 0 0 0 0]]
#
# [[ 0 0 0 0]
# [ 1 0 5 7]
# [ 0 5 12 3]
# [ 5 14 0 9]]
#
# [[ 0 0 0 0]
# [ 5 0 1 0]
# [ 0 4 12 3]
# [10 2 0 15]]]
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/487624.html
上一篇:選擇在特定位置具有給定值的字串
