Python np.选择在广播后不给出期望的结果

Python np.选择在广播后不给出期望的结果,python,numpy,array-broadcasting,Python,Numpy,Array Broadcasting,我想从SuiteCounts中选择maxsuit中指定的第n个元素。我确实广播了maxsuit阵列,所以我确实得到了一个结果,但不是期望的结果。任何关于我在概念上所做的错误的建议都是值得赞赏的。我不明白np.choose(self.maxsuit[:,:,None]-1,self.suitCounts)的结果,这不是我要找的 >>> self.maxsuit Out[38]: array([[3, 3], [1, 1], [1, 1]], dtyp

我想从SuiteCounts中选择maxsuit中指定的第n个元素。我确实广播了maxsuit阵列,所以我确实得到了一个结果,但不是期望的结果。任何关于我在概念上所做的错误的建议都是值得赞赏的。我不明白np.choose(self.maxsuit[:,:,None]-1,self.suitCounts)的结果,这不是我要找的

>>> self.maxsuit
Out[38]: 
array([[3, 3],
       [1, 1],
       [1, 1]], dtype=int64)

>>> self.maxsuit[:,:,None]-1
Out[33]: 
array([[[2],
        [2]],

       [[0],
        [0]],

       [[0],
        [0]]], dtype=int64)
>>> self.suitCounts
Out[34]: 
array([[[2, 1, 3, 0],
        [1, 0, 3, 0]],

       [[4, 1, 2, 0],
        [3, 0, 3, 0]],

       [[2, 2, 0, 0],
        [1, 1, 1, 0]]])
>>> np.choose(self.maxsuit[:,:,None]-1, self.suitCounts)
Out[35]: 
array([[[2, 2, 0, 0],
        [1, 1, 1, 0]],

       [[2, 1, 3, 0],
        [1, 0, 3, 0]],

       [[2, 1, 3, 0],
        [1, 0, 3, 0]]])
预期的结果将是:

[[3,3],[4,3],[2,1]]
您可以使用广播方式索引到数组中,如下所示-

In [415]: val     # Data array
Out[415]: 
array([[[2, 1, 3, 0],
        [1, 0, 3, 0]],

       [[4, 1, 2, 0],
        [3, 0, 3, 0]],

       [[2, 2, 0, 0],
        [1, 1, 1, 0]]])

In [416]: idx     # Indexing array
Out[416]: 
array([[3, 3],
       [1, 1],
       [1, 1]])

In [417]: m,n = val.shape[:2]

In [418]: val[np.arange(m)[:,None],np.arange(n),idx-1]
Out[418]: 
array([[3, 3],
       [4, 3],
       [2, 1]])
使用开放范围阵列的一种更简洁的方法-

In [424]: d0,d1 = np.ogrid[:m,:n]

In [425]: val[d0,d1,idx-1]
Out[425]: 
array([[3, 3],
       [4, 3],
       [2, 1]])

这是我能选择的最好的了

In [23]: np.choose([[1,2,0],[1,2,0]], suitcounts[:,:,:3])
Out[23]: 
array([[4, 2, 3],
       [3, 1, 3]])
choose
更喜欢使用数组列表,而不是单个数组。这应该是为了防止误用。因此,问题可以写成:

In [24]: np.choose([[1,2,0],[1,2,0]], [suitcounts[0,:,:3], suitcounts[1,:,:3], suitcounts[2,:,:3]])
Out[24]: 
array([[4, 2, 3],
       [3, 1, 3]])
其思想是根据索引数组从3个子数组中选择项,如:

In [25]: np.array([[1,2,0],[1,2,0]])
Out[25]: 
array([[1, 2, 0],
       [1, 2, 0]])
输出将在形状上与索引数组匹配。choise数组的形状也匹配,因此我使用了
[…,:3]

第一列的值从
suitecounts[1,:,:3]
中选择,第二列的值从
suitecounts[2…]
等中选择

choose
限制为32个选项;这是广播机制施加的限制

说到广播,我可以简化表达

In [26]: np.choose([1,2,0], suitcounts[:,:,:3])
Out[26]: 
array([[4, 2, 3],
       [3, 1, 3]])
这广播
[1,2,0]
以匹配子阵列的2x3形状

我可以通过重新排列列来获得目标顺序:

In [27]: np.choose([0,1,2], suitcounts[:,:,[2,0,1]])
Out[27]: 
array([[3, 4, 2],
       [3, 3, 1]])

太好了,只是想知道,有没有一种方法可以使用np。选择?@nickpick抱歉,我没有使用
np。选择
太多,所以我帮不了你。我只是更喜欢直接的方式。有道理。你似乎是一个花式索引的专家。你有什么可以推荐的文献吗?@nickpick嗯,这些文献看起来相当全面。虽然就我而言,我是通过练习来学习的,特别是有这么多问题。特别是在谈到花式索引和高级索引时,我们的想法是对穿过该dim长度的dim使用范围数组,也就是说,如果有意义的话,我们在该dim上的每一长度有一个索引。如果选择dim上的所有元素,请使用
。简单地说就是这个想法。我可以用
choose
来近似你的情况,但是合身性差
choose
在如此简单的问题中很少见。