Python 如何分配从解包triu_索引获得的numpy切片视图
我试图根据triu_指数得到的指数,为4-张量的切片赋值。但是,我只能将值分配给切片视图,而不是底层数据 我用了这篇文章 获取4x4张量的6x6切片。我看过很多文章,其中有可能将数据分配给数组切片,但我不清楚为什么我的语法不能用于此目的Python 如何分配从解包triu_索引获得的numpy切片视图,python,numpy,Python,Numpy,我试图根据triu_指数得到的指数,为4-张量的切片赋值。但是,我只能将值分配给切片视图,而不是底层数据 我用了这篇文章 获取4x4张量的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)
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矩阵。使用
triu_索引编制索引
生成副本;这些索引由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]
是一个1d数组-从x
中选择值
我们可以使用标量或兼容数组(1d)直接为其赋值:
但我们不能再添加一层索引
在您的4d案例中:
In [56]: t2 = np.arange(4**4).reshape(4,4,4,4)
t2[idx]
生成一个(6,4,4)数组,一个副本。下一层索引生成(6,6):
如果我两次应用idx
的两个元素,我得到该元素的对角线(6,6):
我可以使用以下工具一步完成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]],
....
我对[idx[0][:,None],idx[1][:,None]]与[idx]相反的作用感到困惑。[:,None]通常做什么?它添加了一个维度。它将具有形状(6,)的
idx[0]
数组更改为具有形状(6,1)的“列向量”。你们很多人需要阅读广播和“高级索引”。
In [58]: t2[idx[0],idx[1],idx[0],idx[1]]
Out[58]: array([ 17, 34, 51, 102, 119, 187])
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]])
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]],
....