Python np.作业的压缩

Python np.作业的压缩,python,numpy,Python,Numpy,我有t.shape=(M,N),现在我想给数组的一部分赋值v,该部分用变量M和N索引m是一个数组,n或者int或者也是一个数组。 如果n是一个数组,我会m=m。重塑(-1,1)。这对于像这样的访问非常有效 t[m, n] 然后我可以使用 np.squeeze(t[m, n]) 删除之前添加的附加维度(如果n为int) 然而,如果我这样做 t[m, n] = v 它不会工作,因为如果n是int,v.shape=(m.size,),即v只有一个维度。我可以检查n是否为整数,并相应地更改逻辑(要

我有
t.shape=(M,N)
,现在我想给数组的一部分赋值
v
,该部分用变量
M
N
索引
m
是一个数组,
n
或者
int
或者也是一个数组。 如果
n
是一个数组,我会
m=m。重塑(-1,1)
。这对于像这样的访问非常有效

t[m, n]
然后我可以使用

np.squeeze(t[m, n])
删除之前添加的附加维度(如果
n
int

然而,如果我这样做

t[m, n] = v
它不会工作,因为如果
n
int
v.shape=(m.size,)
,即
v
只有一个维度。我可以检查
n
是否为整数,并相应地更改逻辑(要么不向
m
添加维度,要么也向
v
添加维度)

有没有更优雅的解决方案(
np.squence(t[m,n])=v
会更好,但显然它不是这样工作的)

编辑:

具体例子:

def change_data(data, slices, channels, values):
    data[slices.reshape(-1, 1), channels] = values

data = np.random.randint(low=0, high=10, size=(10, 4))
slices = np.arange(4)
channels = [2]
values = np.squeeze(np.random.randint(low=0, high=10, size=(slices.size, len(channels)))) # The values come as a list
try:
    change_data(data, slices, channels, values) # Does not work
    print("Single channel does work")
except:
    print("Single channel does not work")
channels = [1, 2]
values = np.squeeze(np.random.randint(low=0, high=10, size=(slices.size, len(channels))))
try:
    change_data(data, slices, channels, values) # Works
    print("Multi channel does work")
except:
    print("Multi channel does not work")
在这个简单的例子中,这看起来有点可笑,因为我这里有一个额外的
np.squence
操作,但是根据数组的维数,这可能有点麻烦,因此如果我可以“挤压”索引选择,问题就会解决。我希望现在更清楚了

In [44]: data = np.arange(40).reshape(10,4)                                               
通过制作第一个索引(4,1)形状,我们可以使用各种大小的第二个数组进行索引:

In [46]: data[np.arange(4)[:,None],[2]]                                                   
Out[46]: 
array([[ 2],
       [ 6],
       [10],
       [14]])
In [47]: data[np.arange(4)[:,None],[1,2]]                                                 
Out[47]: 
array([[ 1,  2],
       [ 5,  6],
       [ 9, 10],
       [13, 14]])
第一个结果是(4,1)形状,第二个结果是(4,2)

通过
挤压
我们得到(4,),相当于索引:

In [48]: data[np.arange(4),2]                                                             
Out[48]: array([ 2,  6, 10, 14])
np.ix
生成类似的索引集,例如(4,1)和(1,2)

(4,1)和(1,1):

(m,1)使用(1,n)进行广播以产生(m,n)结果。(n,)和(1,n)一样有效——同样是广播规则

通过更改,您希望为该(m,n)块指定一个值。在这种情况下,a(4,2)起作用,a(4,1)也起作用。但您希望分配一个(4,)。但通过广播(4),可以广播到(1,4),但不能广播到(4,1)。它可以添加前导维度,但不能添加尾随维度

In [51]: data[np.arange(4)[:,None],[2]]=np.ones(4)                                        
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-51-9245de6331ce> in <module>
----> 1 data[np.arange(4)[:,None],[2]]=np.ones(4)

ValueError: shape mismatch: value array of shape (4,) could not be 
    broadcast to indexing result of shape (4,1)
In [52]: data[np.arange(4)[:,None],[2]] = np.ones((4,1))    # (4,1) into (4,1)
# (4,1) also goes into a (4,2)
In [53]: data[np.arange(4),[2]] = np.ones(4)   # (4,) into (4,)
In [55]: data[np.arange(4)[:,None],[1,2]] = np.zeros(2)  # (2,) into (4,2) 
[51]中的
:数据[np.arange(4)[:,无],[2]=np.one(4)
---------------------------------------------------------------------------
ValueError回溯(最近一次调用上次)
在里面
---->1数据[np.arange(4)[:,无],[2]]=np.ones(4)
ValueError:形状不匹配:形状(4,)的值数组无法匹配
广播到形状的索引结果(4,1)
在[52]中:数据[np.arange(4)[:,无],[2]=np.one((4,1))#(4,1)转化为(4,1)
#(4,1)也进入a(4,2)
在[53]中:数据[np.arange(4),[2]]=np.one(4)#(4,)到(4,)
在[55]中:数据[np.arange(4)[:,None],[1,2]=np.zero(2)#(2,)转化为(4,2)

flat
可以用来以1d的方式分配值,但它在这里不起作用,因为
data[np.arange(4)[:,None],[1,2]
是一个副本,如果它以任何方式使用,除了直接在
\uuu setitem\uuuuu
案例中,
data[…]=…
给出一些具体的例子。很难想象你在做什么,否则。虽然我可能可以自己构造一些示例,但我希望您能完成这些工作。@hpaulj感谢您抽出时间。我添加了一个具体的例子这使问题更加清晰,我尤其不知道上一段提到的np.ix和setitem限制,非常感谢您的解释!
In [50]: np.ix_(np.arange(4),[2])                                                         
Out[50]: 
(array([[0],
        [1],
        [2],
        [3]]), array([[2]]))
In [51]: data[np.arange(4)[:,None],[2]]=np.ones(4)                                        
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-51-9245de6331ce> in <module>
----> 1 data[np.arange(4)[:,None],[2]]=np.ones(4)

ValueError: shape mismatch: value array of shape (4,) could not be 
    broadcast to indexing result of shape (4,1)
In [52]: data[np.arange(4)[:,None],[2]] = np.ones((4,1))    # (4,1) into (4,1)
# (4,1) also goes into a (4,2)
In [53]: data[np.arange(4),[2]] = np.ones(4)   # (4,) into (4,)
In [55]: data[np.arange(4)[:,None],[1,2]] = np.zeros(2)  # (2,) into (4,2)