我试图根据使用triu_indices获得的索引将值分配给4张量的切片。但是,我只能为切片视图分配值,而不能为基础数据分配值。
我用过这篇文章
How to unpack a tuple when indexing?
获得4x4x4x4张量的6x6切片。我看过很多文章,可以在其中为数组切片分配数据,但是我不清楚为什么我的语法无法实现此目的。
import numpy as np
t_vec = np.ones(6,6)
n_occs = 4
n_nnoccs = 4
t2 = np.zeros((n_noccs, n_noccs, n_occs, n_occs)).astype(np.float)
O = (np.triu_indices(n_occs, 1))
t2[O][(slice(None),) + V] = t_vec
t2[V][(slice(None),) + O] = t_vec
预期结果是将t2的256个条目中的72个替换为1。实际输出是原始的0矩阵。
答案 0 :(得分:1)
用triu_indices
编制索引会产生一个副本;这些索引是由where
函数产生的,并执行高级索引编制:
In [40]: x = np.arange(9).reshape(3,3)
In [41]: idx = np.triu_indices(3)
In [42]: idx
Out[42]: (array([0, 0, 0, 1, 1, 2]), array([0, 1, 2, 1, 2, 2]))
In [43]: x[idx]
Out[43]: array([0, 1, 2, 4, 5, 8])
请注意,Out[43]
是一维数组-从x
中选择的值。
我们可以使用标量或兼容数组(1d)直接为其分配:
In [44]: x[idx] = 0
In [45]: x
Out[45]:
array([[0, 0, 0],
[3, 0, 0],
[6, 7, 0]])
In [46]: x[idx] = np.arange(1,7)
In [47]: x
Out[47]:
array([[1, 2, 3],
[3, 4, 5],
[6, 7, 6]])
但是我们不能添加另一层索引。
在您的4d情况下:
In [56]: t2 = np.arange(4**4).reshape(4,4,4,4)
t2[idx]
产生一个(6,4,4)数组,一个副本。下一层索引将产生(6,6):
In [57]: t2[idx][:,idx[0],idx[1]]
Out[57]:
array([[ 17, 18, 19, 22, 23, 27],
[ 33, 34, 35, 38, 39, 43],
[ 49, 50, 51, 54, 55, 59],
[ 97, 98, 99, 102, 103, 107],
[113, 114, 115, 118, 119, 123],
[177, 178, 179, 182, 183, 187]])
如果我两次应用idx
的2个元素,我将得到对角(6,6):
In [58]: t2[idx[0],idx[1],idx[0],idx[1]]
Out[58]: array([ 17, 34, 51, 102, 119, 187])
我可以一步完成4d索引编制:
In [59]: t2[idx[0][:,None],idx[1][:,None],idx[0],idx[1]]
Out[59]:
array([[ 17, 18, 19, 22, 23, 27],
[ 33, 34, 35, 38, 39, 43],
[ 49, 50, 51, 54, 55, 59],
[ 97, 98, 99, 102, 103, 107],
[113, 114, 115, 118, 119, 123],
[177, 178, 179, 182, 183, 187]])
我可以为其分配值,然后修改t2
。
In [60]: t2[idx[0][:,None],idx[1][:,None],idx[0],idx[1]]=0
In [61]: t2
Out[61]:
array([[[[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[ 12, 13, 14, 15]],
[[ 16, 0, 0, 0],
[ 20, 21, 0, 0],
[ 24, 25, 26, 0],
[ 28, 29, 30, 31]],
....