![](/img/trans.png)
[英]How to convert a python dictionary to an 2D array and pad wherever there is mismatch in length?
[英]How to pad a 2d array with variable length per row on the left and right to form a bigger 2d array
我有一個二維數組
small = np.arange(9).reshape((3, 3))
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
我想應用填充,每一行填充左側的變量0。 並確保結果2d數組的形狀為3 x8。(右側填充0s)
offset = np.array([1, 3, 2])
這樣結果看起來像
array([[ 0., 0., 1., 2., 0., 0., 0., 0.],
[ 0., 0., 0., 3., 4., 5., 0., 0.],
[ 0., 0., 6., 7., 8., 0., 0., 0.]])
實現此目標的最佳方法是什么?
感謝@Divakar解決方案。 我對以下方法進行了一些基准測試。
def f1(small, offset, ncols):
nrows, num_small_cols = small.shape
big = np.zeros((nrows, ncols))
inner = np.empty_like(small, dtype=np.int64)
for i in range(num_small_cols):
inner[:, i] = offset + i
big[np.arange(nrows)[:, None], inner] = small
return big
def f2(small, offset, ncols):
n = small.shape[1]
r = np.arange(ncols)
offset2 = offset[:,None]
# This took a lot of time
mask = (offset2 <= r) & (offset2 + n > r)
out = np.zeros_like(mask, dtype=np.float64)
out[mask] = small.ravel()
return out
def f3(small, offset, ncols):
n = small.shape[1]
m = ncols - n
small_pad = np.zeros((len(small), n + 2*m))
small_pad[:,m:m+n] = small
w = view_as_windows(small_pad, (1,ncols))[:,:,0]
return w[np.arange(len(offset)), ncols-offset-n]
n = 10000
offset = np.repeat(np.array([1, 3, 2]), n)
small = np.random.rand(n * 3, 5)
%timeit f1(small, offset, 9)
# 1.32 ms
%timeit f2(small, offset, 9)
# 2.24 ms
%timeit f3(small, offset, 9)
# 1.3 ms
方法1
我們可以使用broadcasting
來創建一個掩碼,以分配給這些位置,然后分配給以零開頭的數組-
def pad_offsetpos(small, ncols):
n = small.shape[1]
r = np.arange(ncols)
mask = (offset[:,None] <= r) & (offset[:,None]+n > r)
out = np.zeros(mask.shape)
out[mask] = small.ravel()
return out
樣品運行-
In [327]: small
Out[327]:
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
In [328]: offset
Out[328]: array([1, 3, 2])
In [329]: pad_offsetpos(small, ncols=8)
Out[329]:
array([[0., 0., 1., 2., 0., 0., 0., 0.],
[0., 0., 0., 3., 4., 5., 0., 0.],
[0., 0., 6., 7., 8., 0., 0., 0.]])
方法#2
我們還可以np.lib.stride_tricks.as_strided
基於np.lib.stride_tricks.as_strided
的scikit-image's view_as_windows
進行有效的補丁提取之后,在輸入數組的兩邊都填充足夠的零-
from skimage.util.shape import view_as_windows
def pad_offsetpos_strided(small, ncols):
n = small.shape[1]
m = ncols - n
small_pad = np.zeros((len(small), n + 2*m))
small_pad[:,m:m+n] = small
w = view_as_windows(small_pad, (1,ncols))[:,:,0]
return w[np.arange(len(offset)), ncols-offset-n]
PaddedMat=numpy.zeros(shape=[3,8],dtype="float")
然后循環填充它。
PaddedMat[i,offset[i]:offset[i]+3]=small[i,:]
等等...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.