我想将一些函数应用于Theano的张量。这是我的numpy版本脚本。但是,在将其转换为Theano版本时,我迷失了。
例如,我想转换
array([[[0, 0, 1, 2, 3],
[0, 1, 2, 3, 4]]])
到
array([[[0, 0, 3, 2, 1],
[0, 4, 3, 2, 1]]])
我的numpy脚本如下:
def reverse_and_shift(vec):
'''
Returns reversed array of the given vector except the leading 0's.
vec: 1-d array.
>>> reverse_and_shift(np.array([0,0,1,2,3]))
array([0, 0, 3, 2, 1])
'''
reversed = vec[::-1]
num_zero = len(vec) - np.count_nonzero(vec)
shifted = np.roll(reversed, num_zero)
return shifted
np.apply_along_axis(reverse_and_shift, -1, A)
如何在张量中执行此操作?
答案 0 :(得分:0)
在不同维度的数组上尝试:
对于1d阵列,它不会添加任何功能:
In [36]: A=np.arange(10)
In [38]: np.apply_along_axis(reverse_and_shift,-1,A)
Out[38]: array([0, 9, 8, 7, 6, 5, 4, 3, 2, 1])
In [39]: reverse_and_shift(A)
Out[39]: array([0, 9, 8, 7, 6, 5, 4, 3, 2, 1])
对于二维数组,它相当于在第一维上迭代,将函数应用到最后一个(-1
):
In [41]: A=np.arange(9).reshape(3,3)
In [42]: np.apply_along_axis(reverse_and_shift,-1,A)
Out[42]:
array([[0, 2, 1],
[5, 4, 3],
[8, 7, 6]])
In [43]: reverse_and_shift(A[0,:])
Out[43]: array([0, 2, 1])
In [44]: reverse_and_shift(A[1,:])
Out[44]: array([5, 4, 3])
In [45]: reverse_and_shift(A[2,:])
Out[45]: array([8, 7, 6])
In [46]: np.array([reverse_and_shift(x) for x in A])
Out[46]:
array([[0, 2, 1],
[5, 4, 3],
[8, 7, 6]])
对于3d,它会迭代前两个维度的所有值,将您的函数应用到最后一个维度。
In [48]: A=np.arange(8).reshape(2,2,2)
In [49]: np.apply_along_axis(reverse_and_shift,-1,A)
Out[49]:
array([[[0, 1],
[3, 2]],
[[5, 4],
[7, 6]]])
有多种方法可以对这些值进行自己的迭代。最简单的方法之一是将数组重新整形为2d(然后返回)
In [50]: np.array([reverse_and_shift(x) for x in A.reshape(-1,2)])
Out[50]:
array([[0, 1],
[3, 2],
[5, 4],
[7, 6]])
In [51]: _.reshape(2,2,2)
Out[51]:
array([[[0, 1],
[3, 2]],
[[5, 4],
[7, 6]]])
如果应用程序轴是最后一个或第一个,则此重塑方法最简单。如果要沿中轴应用,可能更容易先交换某个轴,将该轴移动到最后。
apply_along_axis
是用Python编写的,因此您可以阅读它,并根据需要提取相关部分。所有的迭代都是用Python完成的,所以如果你自己进行迭代,那么性能就没有损失。
=======================
在您的示例中,A
是3d;应用保留形状
In [70]: A.shape
Out[70]: (1, 2, 5)
In [71]: np.apply_along_axis(reverse_and_shift,-1,A)
Out[71]:
array([[[0, 0, 3, 2, 1],
[0, 4, 3, 2, 1]]])
In [72]: _.shape
Out[72]: (1, 2, 5)
重塑迭代案例删除了一个维度,必须将其添加回来。
In [73]: np.array([reverse_and_shift(x) for x in A.reshape(-1,A.shape[-1])])
Out[73]:
array([[0, 0, 3, 2, 1],
[0, 4, 3, 2, 1]])
In [74]: _.shape
Out[74]: (2, 5)
apply_along_axis
(粗略地)
outarr=np.zeros_like(A)
for <all applicable i,j>:
ind = (i,j,slice(None))
outarr[ind] = reverse_and_shift(A[ind])