假设我numpy.ndarray
shape (2,3,2)
如下,
arr = np.array([[[1,3], [2,5], [1,2]],[[3,3], [6,5], [5,2]]])
我想以这样的方式重塑它:
arr.shape == (2,3)
arr == [[(1,3), (2,5), (1,2)],[(3,3), (6,5), (5,2)]]
和
arr
的每个值都是2 tuple
我想这样做的原因是我想沿着3dimensional数组的轴0取最小值,但我想保留与行配对的最小值的值。
arr = np.array(
[[[1, 4],
[2, 1],
[5, 2]],
[[3, 3],
[6, 5],
[1, 7]]])
print(np.min(arr, axis=0))
>>> [[1,3],
[2,1],
[1,2]]
>>>Should be
[[1,4],
[2,1],
[1,7]]
如果数组包含元组,那么它将是2维的,并且用于最小化的比较运算符仍然可以正常运行, 所以我会得到正确的结果。但是除了迭代数组之外,我还没有找到任何方法来实现这一点,这在实现中是低效且明显的。
是否可以在numpy中有效地执行此转换?
答案 0 :(得分:3)
根本不使用元组 - 只需将其视为结构化数组,它支持您之后的词汇比较:
a = np.array([[[1,3], [2,5], [1,2]],[[3,3], [6,5], [5,2]]])
a_pairs = a.view([('f0', a.dtype), ('f1', a.dtype)]).squeeze(axis=-1)
min_pair = np.partition(a_pairs, 0, axis=0)[0] # min doesn't work on structured types :(
array([(1, 4), (2, 1), (1, 7)],
dtype=[('f0', '<i4'), ('f1', '<i4')])
答案 1 :(得分:1)
首先,让我们找出要采取的对:
first_eq = arr[0,:,0] == arr[1,:,0]
which_compare = np.where(first_eq, 1, 0)[0]
winner = arr[:,:,which_compare].argmin(axis=0)
这里,first_eq
为True,其中第一个元素匹配,因此我们需要比较第二个元素。你的例子中是[False, False, False]
。 which_compare
然后是[0, 0, 0]
(因为每对的第一个元素是我们要比较的)。最后,winner
告诉我们沿着第二轴选择哪两对。它是[0, 0, 1]
。
最后一步是提取获奖者:
arr[winner, np.arange(arr.shape[1])]
即,沿第二轴的每个点取得胜利者(0或1)。
答案 2 :(得分:1)
这是一种方式 -
# Get each row being fused with scaling based on scale being decided
# based off the max values from the second col. Get argmin indices.
idx = (arr[...,1] + arr[...,0]*(arr[...,1].max()+1)).argmin(0)
# Finally use advanced-indexing to get those rows off array
out = arr[idx, np.arange(arr.shape[1])]
示例运行 -
In [692]: arr
Out[692]:
array([[[3, 4],
[2, 1],
[5, 2]],
[[3, 3],
[6, 5],
[5, 1]]])
In [693]: out
Out[693]:
array([[3, 3],
[2, 1],
[5, 1]])