什么是numpy apply_along_axis的theano对应物?

时间:2016-08-03 12:40:43

标签: numpy theano

我想将一些函数应用于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)

如何在张量中执行此操作?

1 个答案:

答案 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])