为了账号安全,请及时绑定邮箱和手机立即绑定

np.squeeze 进行作业

np.squeeze 进行作业

POPMUISE 2022-03-09 21:05:51
我有t.shape=(M, N),现在我想为v数组的一部分分配新值,该数组用变量m和n. m是一个数组,n或者也是int一个数组。我做m=m.reshape(-1, 1)的n是一个数组。这适用于访问t[m, n]然后我可以使用np.squeeze(t[m, n])删除之前添加的附加维度(如果n是int)。但是,如果我这样做t[m, n] = v它不起作用,因为 if nis int, v.shape=(m.size,), iev只有一个维度。我可以检查是否n是整数并相应地更改逻辑(不添加维度m或添加维度v)。有没有更优雅的解决方案(np.squeeze(t[m, n]) = v会很好,但显然这不是它的工作原理)?编辑:具体例子:def change_data(data, slices, channels, values):    data[slices.reshape(-1, 1), channels] = valuesdata = 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 listtry:    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.squeeze这里有一个额外的操作,但是根据数组有多少维度,这可能有点麻烦,因此如果我可以“挤压”索引选择,问题将是解决了。我希望现在更清楚...
查看完整描述

1 回答

?
冉冉说

TA贡献1877条经验 获得超1个赞

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)。


我们得到squeeze(4,),相当于索引:


In [48]: data[np.arange(4),2]                                                             

Out[48]: array([ 2,  6, 10, 14])

np.ix_生成相似的索引集,例如 (4,1) 和 (1,2)


In [49]: np.ix_(np.arange(4),[1,2])                                                       

Out[49]: 

(array([[0],

        [1],

        [2],

        [3]]), array([[1, 2]]))

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


In [50]: np.ix_(np.arange(4),[2])                                                         

Out[50]: 

(array([[0],

        [1],

        [2],

        [3]]), array([[2]]))

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


通过更改,您想为该 (m,n) 块分配一个值。在这种情况下,(4,2)和(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) 

flat可用于以 1d 方式分配值,但它在这里不起作用,因为 data[np.arange(4)[:,None],[1,2]]它是一个副本,如果它以任何方式使用,除非直接在__setitem__case 中使用,data[...] = ....


查看完整回答
反对 回复 2022-03-09
  • 1 回答
  • 0 关注
  • 267 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号