给出一个ndarray
,我想沿一个轴挤压它,这样沿该维度的元素将形成元组,即。 e。它将产生ndarray
个元组,其维数比父ndarray
小一维。
假设我下面有一个三维数组,它基本上是由numpy.indices
从一个二维数组中生成的。
idx = array([[[0, 0, 0, 0],
[1, 1, 1, 1],
[2, 2, 2, 2]],
[[0, 1, 2, 3],
[0, 1, 2, 3],
[0, 1, 2, 3]]])
我尝试将numpy.apply_along_axis
与tuple()
一起使用。
numpy.apply_along_axis(tuple, 0, idx)
它没有用。因此,在tuple()
周围创建了一个虚拟包装器,并传递了该函数以检查tuple()
是否按预期工作。
def dtuple(x):
print(tuple(x))
return tuple(x)
输出为:
(0, 0)
(0, 1)
(0, 2)
(0, 3)
(1, 0)
(1, 1)
(1, 2)
(1, 3)
(2, 0)
(2, 1)
(2, 2)
(2, 3)
array([[[0, 0, 0, 0],
[1, 1, 1, 1],
[2, 2, 2, 2]],
[[0, 1, 2, 3],
[0, 1, 2, 3],
[0, 1, 2, 3]]])
很显然,tuple()
正常工作,但是奇怪的是,它没有返回ndarray
个对象的tuple
,而是返回了相同的ndarray
。我还尝试传递idx.astype(object)
而不是仅传递idx
,但这也不起作用。请注意,我试图避免在这里for
循环。预期输出如下:
array([[(0, 0), (0, 1), (0, 2), (0, 3)],
[(1, 0), (1, 1), (1, 2), (1, 3)],
[(2, 0), (2, 1), (2, 2), (2, 3)]], dtype=object)
答案 0 :(得分:1)
让我们尝试一些替代方法:
In [563]: x=np.arange(12).reshape(3,4)
In [564]: np.apply_along_axis(lambda i:[12],1,x)
Out[564]:
array([[12],
[12],
[12]])
In [565]: np.apply_along_axis(lambda i:(1,2,3),1,x)
Out[565]:
array([[1, 2, 3],
[1, 2, 3],
[1, 2, 3]])
In [566]: np.apply_along_axis(lambda i:i,1,x)
Out[566]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
In [567]: np.apply_along_axis(lambda i:i*2,1,x)
Out[567]:
array([[ 0, 2, 4, 6],
[ 8, 10, 12, 14],
[16, 18, 20, 22]])
看一下文档:
out : ndarray (Ni..., Nj..., Nk...)
The output array. The shape of `out` is identical to the shape of
`arr`, except along the `axis` dimension. This axis is removed, and
replaced with new dimensions equal to the shape of the return value
of `func1d`. So if `func1d` returns a scalar `out` will have one
fewer dimensions than `arr`.
无论函数是否返回数字,列表,元组或数组,它仍将其作为维。 dtype仍为数字。
您为什么要避免循环? apply_along_axis
不会避免循环,只会将其隐藏在函数中。
这是一个不错的循环:
In [578]: arr = np.empty(x.shape[0],object)
In [579]: for i,v in enumerate(x):
...: arr[i] = tuple(v.tolist())
...:
In [580]: arr
Out[580]: array([(0, 1, 2, 3), (4, 5, 6, 7), (8, 9, 10, 11)], dtype=object)
====
使用您的idx
,这是通过结构化数组的一种方法。比我想要的要复杂得多,但这是我睡觉的时间。
In [596]: arr = np.zeros((3,4),'i,i')
In [597]: arr['f0']=idx[0]
In [598]: arr['f1']=idx[1]
In [599]: arr
Out[599]:
array([[(0, 0), (0, 1), (0, 2), (0, 3)],
[(1, 0), (1, 1), (1, 2), (1, 3)],
[(2, 0), (2, 1), (2, 2), (2, 3)]],
dtype=[('f0', '<i4'), ('f1', '<i4')])
In [600]: arr.tolist()
Out[600]:
[[(0, 0), (0, 1), (0, 2), (0, 3)],
[(1, 0), (1, 1), (1, 2), (1, 3)],
[(2, 0), (2, 1), (2, 2), (2, 3)]]
In [601]: arr1=np.empty((3,4),object)
In [602]: arr1[...] = _600
In [603]: arr1
Out[603]:
array([[(0, 0), (0, 1), (0, 2), (0, 3)],
[(1, 0), (1, 1), (1, 2), (1, 3)],
[(2, 0), (2, 1), (2, 2), (2, 3)]], dtype=object)