我们假设我有一个数组x = np.random.normal(size=(300, 300))
,我希望使用(2, 2, 300, 300)
创建一个大小为x
的对角矩阵。我的第一个方法是做到
import numpy as np
x = np.random.normal(size=(300, 300))
array = np.array([
[x, 0.],
[0., x]
])
但是,这样做时,我会得到一个大小为(2, 2)
的数组。是否有numpy
函数将元素重铸为相同的大小?假设列表的所有数组都是相同的形状,并且所有其他元素都是floats
。
修改
我可以补充说,仅定义一个空数组并将对角线设置为x
不是解决方案。
编辑2 这是一个样本
import numpy as np
x = np.random.normal(size=(3, 3))
array = np.zeros((2, 2, *x.shape))
array[0, 0] = array[1, 1] = x
print(array)
屈服
[[[[-1.57346701 -1.00813871 -0.72318135]
[ 0.11852539 1.144298 1.38860739]
[ 0.64571669 0.47474236 0.294049 ]]
[[ 0. 0. 0. ]
[ 0. 0. 0. ]
[ 0. 0. 0. ]]]
[[[ 0. 0. 0. ]
[ 0. 0. 0. ]
[ 0. 0. 0. ]]
[[-1.57346701 -1.00813871 -0.72318135]
[ 0.11852539 1.144298 1.38860739]
[ 0.64571669 0.47474236 0.294049 ]]]]
答案 0 :(得分:3)
对于长度为2
的输出的前两个维度的情况,已发布的解决方案 -
array[0, 0] = array[1, 1] = x
会快速且可读。
我会尝试解决通用长度。
方法#1:以下是masking
的一种方法 -
m = 2 # length along first two axes of o/p
out = np.zeros((m,m) + x.shape)
out[np.eye(m,dtype=bool)] = x
方法#2:在前两个轴合并视图上使用赋值,从而避免创建任何蒙版并利用快速切片分配 -
out = np.zeros((m,m) + x.shape)
out.reshape((-1,) + x.shape)[::m+1] = x
通用模式案例
我们会利用np.broadcast_to
来解决这种情况 -
def resizer(tup):
shp = x.shape
out_shp = (len(tup), -1) + shp
list_arrs = [np.broadcast_to(j, shp) for i in tup for j in i]
return np.asarray(list_arrs).reshape(out_shp)
示例运行 -
In [121]: x
Out[121]:
array([[55, 58, 75],
[78, 78, 20],
[94, 32, 47]])
In [122]: array0 = [
...: [x, 0, 1, 2],
...: [1, 2, 0, x]
...: ]
In [123]: resizer(array0)
Out[123]:
array([[[[55, 58, 75],
[78, 78, 20],
[94, 32, 47]],
[[ 0, 0, 0],
[ 0, 0, 0],
[ 0, 0, 0]],
[[ 1, 1, 1],
[ 1, 1, 1],
[ 1, 1, 1]],
[[ 2, 2, 2],
[ 2, 2, 2],
[ 2, 2, 2]]],
.....
[[55, 58, 75],
[78, 78, 20],
[94, 32, 47]]]])
答案 1 :(得分:3)
您可以通过以下方式关注您的第一个想法:
x = np.random.normal(size=(300, 300))
O = np.zeros_like(x)
r = np.array([[x,O],[O,x]])
In [153]: r.shape
Out[153]: (2, 2, 300, 300)