Вот трюк, использующий np.bincount
:
a = np.array([[1, 0, 0, 1], [0, 1, 0, 1]])
N = 5
X,Y = a.nonzero()
Z = np.ceil(np.random.gamma(1,3,X.shape)).astype(int)
Z
# array([ 2, 1, 15, 2])
flat = np.ravel_multi_index((X[Z<N],Y[Z<N],Z[Z<N]),a.shape+(N,))
np.bincount(flat,None,a.size*N).reshape(*a.shape,N)
# array([[[0, 0, 1, 0, 0],
# [0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0],
# [0, 1, 0, 0, 0]],
#
# [[0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0],
# [0, 0, 1, 0, 0]]])
ОБНОВЛЕНИЕ: С кратностями:
a = np.array([[1, 0, 0, 3], [0, 10, 0, 1]])
N = 5
X,Y = a.nonzero()
times = a[X,Y]
X = X.repeat(times)
Y = Y.repeat(times)
Z = np.ceil(np.random.gamma(1,3,X.shape)).astype(int)
flat = np.ravel_multi_index((X[Z<N],Y[Z<N],Z[Z<N]),a.shape+(N,))
np.bincount(flat,None,a.size*N).reshape(*a.shape,N)
# array([[[0, 1, 0, 0, 0],
# [0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0],
# [0, 1, 0, 0, 0]],
#
# [[0, 0, 0, 0, 0],
# [0, 4, 2, 0, 3],
# [0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0]]])