gpt4 book ai didi

python - 如何在左侧和右侧填充每行可变长度的二维数组以形成更大的二维数组

转载 作者:行者123 更新时间:2023-11-28 22:19:05 24 4
gpt4 key购买 nike

我有一个像这样的二维数组

small = np.arange(9).reshape((3, 3))

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

我想应用填充,每一行都在左侧填充变量 0。并确保结果二维数组的形状为 3 x 8。(右侧填充 0)

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

sample 运行-

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基于 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]

关于python - 如何在左侧和右侧填充每行可变长度的二维数组以形成更大的二维数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50042350/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com