2 回答

TA貢獻1816條經驗 獲得超6個贊
我認為你可以使用 2D 卷積在大數組中找到小數組b可以去的地方a。如果您與您一起使用scipy.signal.convolve2d,mode='valid'則只能獲得小陣列“適合”的位置。我認為使用absarays 可以繞過正值和負值(在任一數組中)取消,但我還沒有非常嚴格地測試過這些。
這是我所做的,使用@CypherX 的fill_a_with_b函數進行填充步驟:
import numpy as np
import scipy.signal
# Your input data.
a = np.array([[0, 0, 0, 9],
[0, 0, 0, 7],
[0, 0, 0, 2],
[2, 3, 1, 5]])
b = np.ones((2, 2)) * 3
# Find places where b can go.
allowed = scipy.signal.convolve2d(np.abs(a), np.abs(b), mode='valid')
# Get these locations as (row, col) pairs.
coords = np.stack(np.where(allowed==0)).T
# Choose one of the locations at random.
choice = coords[np.random.randint(coords.shape[0])]
# Use @CypherX's 'fill' function.
def fill_a_with_b(a, b, pos=[0, 0]):
aa = a.copy()
aa[slice(pos[0], pos[0] + b.shape[0]),
slice(pos[1], pos[1] + b.shape[1])] = b.copy()
return aa
# Do the fill thing.
fill_a_with_b(a, b, choice)
這導致(例如)...
array([[0, 0, 0, 9],
[0, 3, 3, 7],
[0, 3, 3, 2],
[2, 3, 1, 5]])

TA貢獻2080條經驗 獲得超4個贊
我會試著給你一個例子。但這將基于一些假設:
您知道 0 跨越一個連續的矩形塊。
中沒有其他零
a
。
如果您想填充一個不連續的零塊,或者在您有一些其他非零值的列/行上有零,您將不得不考慮更復雜的解決方案。
解決方案:將數組隨機插入b
數組a
wherea==0
假設:我們知道a
為零的位置是一組連續的矩形位置。
進口
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
%config InlineBackend.figure_format = 'svg' # 'svg', 'retina'
plt.style.use('seaborn-white')
制作數據
# Make a
shape = (5,5)
a = np.zeros(shape)
a[:,-1] = np.arange(shape[0]) + 10
a[-1,:] = np.arange(shape[1]) + 10
# Make b
b = np.ones((2,2))*2
預處理
b在這里,我們確定on左上角元素的可能插槽位置a。
# Get range of positions (rows and cols) where we have zeros
target_indices = np.argwhere(a==0)
minmax = np.array([target_indices.min(axis=0), target_indices.max(axis=0)])
# Define max position (index) of topleft element of b on a
maxpos = np.dot(np.array([-1,1]), minmax) + minmax[0,:] - (np.array(b.shape) -1)
# Define min position (index) of topleft element of b on a
minpos = minmax[0,:]
列出on的左上角位置ba
Th 函數get_rand_topleftpos()接受minpos和for定義可能的槽位置maxpos的行和列,并返回一個隨機選擇的有效槽位置。我使用 a創建了很多有效的隨機插槽位置,然后只選擇唯一的位置,這樣我們就可以將它們視為圖像。如果您一次只需要一個插槽位置,請選擇。 asize=1size=20size=1
def get_rand_topleftpos(minpos, maxpos, size=1):
rowpos = np.random.randint(minpos[0], high=maxpos[0] + 1, size=size)
colpos = np.random.randint(minpos[1], high=maxpos[1] + 1, size=size)
pos = np.vstack([rowpos, colpos]).T
return (rowpos, colpos, pos)
# Make a few valid positions where the array b could be placed
rowpos, colpos, pos = get_rand_topleftpos(minpos, maxpos, size=20)
# Select the Unique combinations so we could visualize them only
pos = np.unique(pos, axis=0)
放置b并a制作數字
我們制作了一個自定義函數fill_a_with_b()來填充. 該位置將接受 的左上角單元格。abab
def fill_a_with_b(a, b, pos = [0,0]):
aa = a.copy()
aa[slice(pos[0], pos[0] + b.shape[0]),
slice(pos[1], pos[1] + b.shape[1])] = b.copy()
return aa
# Make a few figures with randomly picked position
# for topleft position of b on a
if pos.shape[0]>6:
nrows, ncols = int(np.ceil(pos.shape[0]/6)), 6
else:
nrows, ncols = 1, pos.shape[0]
fig, axs = plt.subplots(nrows = nrows,
ncols = ncols,
figsize=(2.5*ncols,2.5*nrows))
for i, ax in enumerate(axs.flatten()):
if i<pos.shape[0]:
aa = fill_a_with_b(a, b, pos[i,:])
sns.heatmap(aa,
vmin=np.min(aa),
vmax=np.max(aa),
annot=True,
cbar=False,
square=True,
cmap = 'YlGnBu_r',
ax = ax
);
ax.set_title('TopLeftPos: {}'.format(tuple(pos[i,:])),
fontsize=9);
else:
ax.axis('off')
plt.tight_layout()
plt.show()
結果
數組a定義為:
shape = (5,5)
a = np.zeros(shape)
a[:,-1] = np.arange(shape[0]) + 10
a[-1,:] = np.arange(shape[1]) + 10
數組a定義為:
shape = (6,5)
a = np.zeros(shape)
a[:,0] = np.arange(shape[0]) + 10
a[:,-1] = np.arange(shape[0]) + 10
a[-1,:] = np.arange(shape[1]) + 10
添加回答
舉報