簡體   English   中英

如何在 numpy 數組的元素之間插入零?

[英]How to insert zeros between elements in a numpy array?

我有一個 nd 數組,例如:

x = np.array([[1,2,3],[4,5,6]])

我想將最后一個維度的大小加倍,並在元素之間插入零以填充空間。 結果應如下所示:

[[1,0,2,0,3,0],[4,0,5,0,6,0]]

我嘗試使用expand_dimspad來解決它。 但是pad function 不僅在最后一個維度中的每個值之后插入零。 結果的形狀是(3, 4, 2) ,但它應該是(2,3,2)

y = np.expand_dims(x,-1)
z = np.pad(y, (0,1), 'constant', constant_values=0)
res = np.reshape(z,[-1,2*3]

我的代碼的結果:

array([[1, 0, 2, 0, 3, 0],
       [0, 0, 4, 0, 5, 0],
       [6, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0]])

pad如何在每個元素之后的最后一個維度中插入零? 或者有什么更好的方法來解決這個問題?

只需初始化輸出數組並使用slicing分配 -

m,n = x.shape
out = np.zeros((m,2*n),dtype=x.dtype)
out[:,::2] = x

或者堆疊 -

np.dstack((x,np.zeros_like(x))).reshape(x.shape[0],-1)

你可以使用insert函數簡單地完成它:

np.insert(x, [1,2,3], 0, axis=1)

array([[1, 0, 2, 0, 3, 0],
       [4, 0, 5, 0, 6, 0]])

對我發現的一些方法進行了基准測試:
(一)分項指標分配
(2) 步法
(3) 填充
(4) 串聯

def dilation1(X, d):
    Xd_shape = np.multiply(X.shape, d)
    Xd = np.zeros(Xd_shape, dtype=X.dtype)
    Xd[0:Xd_shape[0]:d[0], 0:Xd_shape[1]:d[1]] = X
    return Xd

def dilation2(X, d):
    Xd_shape = np.multiply(X.shape, d)
    Xd = np.zeros(Xd_shape, dtype=X.dtype)
    Xdn = np.lib.stride_tricks.as_strided(Xd, X.shape, np.multiply(Xd.strides, d))
    Xdn[:] = X
    return Xd

def dilation3(X, d):
    Xd = X.reshape((X.shape[0],1,X.shape[1],1))
    Xd = np.pad(Xd, ((0,0),(0,d[0]-1),(0,0),(0,d[1]-1)))
    return Xd.reshape(np.multiply(X.shape,d))

def dilation4(X, d):
    Xd = X.reshape((X.shape[0],1,X.shape[1],1))
    mcol = np.zeros(Xd.shape[:3]+(d[1]-1,))
    Xd = np.concatenate((Xd, mcol), 3)
    mrow = np.zeros((Xd.shape[0],d[0]-1)+Xd.shape[2:])
    Xd = np.concatenate((Xd, mrow), 1)
    return Xd.reshape(np.multiply(X.shape,d))

#Example
b = np.arange(3*3).reshape((3,3))
b
# array([[0, 1, 2],
#        [3, 4, 5],
#        [6, 7, 8]])
dilation1(b, (3,2))
# array([[0, 0, 1, 0, 2, 0],
#        [0, 0, 0, 0, 0, 0],
#        [0, 0, 0, 0, 0, 0],
#        [3, 0, 4, 0, 5, 0],
#        [0, 0, 0, 0, 0, 0],
#        [0, 0, 0, 0, 0, 0],
#        [6, 0, 7, 0, 8, 0],
#        [0, 0, 0, 0, 0, 0],
#        [0, 0, 0, 0, 0, 0]])

#Benchmark
a = np.random.randn(1024,1024)

%timeit -r 20 dilation1(a, (5,5))
#19.7 ms ± 890 µs per loop (mean ± std. dev. of 20 runs, 100 loops each)

%timeit -r 20 dilation2(a, (5,5))
#18.8 ms ± 526 µs per loop (mean ± std. dev. of 20 runs, 100 loops each)

%timeit -r 20 dilation3(a, (5,5))
#101 ms ± 2.32 ms per loop (mean ± std. dev. of 20 runs, 10 loops each)

%timeit -r 20 dilation4(a, (5,5))
#101 ms ± 1.59 ms per loop (mean ± std. dev. of 20 runs, 10 loops each)

所以干脆使用分索引賦值。

沿着expand_dims的行,我們可以使用stack

In [742]: x=np.arange(1,7).reshape(2,-1)
In [743]: x
Out[743]: 
array([[1, 2, 3],
       [4, 5, 6]])
In [744]: np.stack([x,x*0],axis=-1).reshape(2,-1)
Out[744]: 
array([[1, 0, 2, 0, 3, 0],
       [4, 0, 5, 0, 6, 0]])

stack使用expend_dims添加維度; 它就像np.array但可以更好地控制新軸的添加方式。 因此,它是一種散布陣列的便捷方式。

堆棧產生一個(2,4,2)數組,我們重新形成(2,8)。

x*0可以替換為np.zeros_like(x) ,或任何創建相同大小的零數組的東西。

np.stack([x,x*0],axis=1).reshape(4,-1)添加0行。

需要填充新維度的一側

x = np.array( [[1,2,3],[4,5,6]] )
y = np.expand_dims(x,-1)
z = np.pad( y, ((0, 0), (0, 0), (0, 1)) , 'constant', constant_values=0)
res = np.reshape(z, ( x.shape[0] , 2*x.shape[1] ) )
                 
res
 array([[1, 0, 2, 0, 3, 0], [4, 0, 5, 0, 6, 0]])

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM