np.choose 广播后没有给出预期的结果
np.choose not giving desired result after broadcasting
我想从 suitCounts 中选取 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]]
您可以使用 advanced-indexing
作为广播方式对数组进行索引,就像这样 -
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]])
np.ogrid
使用开放范围数组的更简洁的方法 -
In [424]: d0,d1 = np.ogrid[:m,:n]
In [425]: val[d0,d1,idx-1]
Out[425]:
array([[3, 3],
[4, 3],
[2, 1]])
这是我使用 choose 所能做的最好的事情
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]])
想法是 select 来自 3 个子数组的项目,基于索引数组,如:
In [25]: np.array([[1,2,0],[1,2,0]])
Out[25]:
array([[1, 2, 0],
[1, 2, 0]])
输出将在形状上匹配索引数组。选择数组的形状也匹配,因此我使用 [...,:3]
.
第一列的值 select 来自 suitcounts[1,:,:3]
,第二列的值来自 suitcounts[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]])
我想从 suitCounts 中选取 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]]
您可以使用 advanced-indexing
作为广播方式对数组进行索引,就像这样 -
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]])
np.ogrid
使用开放范围数组的更简洁的方法 -
In [424]: d0,d1 = np.ogrid[:m,:n]
In [425]: val[d0,d1,idx-1]
Out[425]:
array([[3, 3],
[4, 3],
[2, 1]])
这是我使用 choose 所能做的最好的事情
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]])
想法是 select 来自 3 个子数组的项目,基于索引数组,如:
In [25]: np.array([[1,2,0],[1,2,0]])
Out[25]:
array([[1, 2, 0],
[1, 2, 0]])
输出将在形状上匹配索引数组。选择数组的形状也匹配,因此我使用 [...,:3]
.
第一列的值 select 来自 suitcounts[1,:,:3]
,第二列的值来自 suitcounts[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]])