【问题标题】:np.apply_along_axis returning multiple valuesnp.apply_along_axis 返回多个值
【发布时间】:2019-06-06 11:14:38
【问题描述】:

我正在将一些函数应用于一个 numpy 数组。

import numpy as np
MATRIX=np.random.rand(5,7)


def F_a(x):
   return 1

def F_b(x):
   return [1,2]
FUNCS=[F_a,F_b]

results=list(map(lambda f:np.apply_along_axis(f,1, MATRIX),FUNCS))

当所有 FUNCS 返回一个标量值时,它会按预期工作。 但是,我的 一些 FUNC 返回可迭代对象(例如可变长度列表)。

如何应用这种方式返回多个值的函数(map + apply_along_axis)?

如果我运行 MVE,我会得到:

[array([1, 1, 1, 1, 1]), array([[1, 2],
        [1, 2],
        [1, 2],
        [1, 2],
        [1, 2]])]

我想要的输出是一个大小为 5x3 的数组,而不是两个数组 5x1 和 5x2

​如果我尝试:

results=np.stack(list(map(lambda f:np.apply_along_axis(f,1, MATRIX),FUNCS)))

我明白了:

ValueError: all input arrays must have the same shape

np.vstacknp.hstack 相同

【问题讨论】:

  • 我在 4D 体积的第三方向使用 np.apply_along_axis,并将结果数组(也是 4D)存储在 numpy 数组中。你能做类似的事情吗?
  • 你需要给一个minimal reproducible example
  • 我正在准备这个
  • 我已经添加了
  • 首先确保您了解apply... 对每个函数的作用。 F_a 产生一个 (5,) 数组,F_b 一个 (5,2)。它将 func 应用于每一行,并将结果收集到具有相同第一维 5 的数组中。第二维取决于 fun 返回的内容(标量或 2 元素列表)

标签: python numpy dictionary lambda


【解决方案1】:

使用轴 1 和 2d 输入,apply_along_axis 只迭代行(其他维度),并返回一个数组,其形状由迭代维度和函数值确定。

如果 fn 返回一个标量,结果就是 (5,),行的大小:

In [291]: np.apply_along_axis(lambda a1: 1, 1,arr)                                                     
Out[291]: array([1, 1, 1, 1, 1])
In [292]: _.shape                                                                                      
Out[292]: (5,)

如果它返回一个列表或单元素数组,则该维度的大小为 1:

In [293]: np.apply_along_axis(lambda a1: [1], 1,arr)                                                   
Out[293]: 
array([[1],
       [1],
       [1],
       [1],
       [1]])
In [294]: _.shape                                                                                      
Out[294]: (5, 1)

其他回报以此类推:

In [295]: np.apply_along_axis(lambda a1: np.arange(4), 1,arr)                                          
Out[295]: 
array([[0, 1, 2, 3],
       [0, 1, 2, 3],
       [0, 1, 2, 3],
       [0, 1, 2, 3],
       [0, 1, 2, 3]])
In [296]: _.shape                                                                                      
Out[296]: (5, 4)
In [297]: np.apply_along_axis(lambda a1: a1, 1,arr)                                                    
Out[297]: 
array([[0., 0., 0.],
       [0., 0., 0.],
       [0., 0., 0.],
       [0., 0., 0.],
       [0., 0., 0.]])
In [298]: _.shape                                                                                      
Out[298]: (5, 3)

这与从列表理解中制作数组相同:

In [302]: [(lambda a1:1)(row) for row in arr]                                                          
Out[302]: [1, 1, 1, 1, 1]
In [303]: [(lambda a1:[1,2])(row) for row in arr]                                                      
Out[303]: [[1, 2], [1, 2], [1, 2], [1, 2], [1, 2]]

如果是这样的话,apply_along_axis 这样的二维输入只不过是一种符号方便。对于更大的尺寸,便利性更大。但与更直接的迭代相比,它并没有提高速度。

如果您不理解apply_along_axis,或者在使用它时遇到问题,请不要打扰。做你理解的那种迭代。

====

如果

def F_a(x):
    return [1]

您的列表映射将生成 (5,1) 和 (5,2) 数组,然后可以在第二个轴上连接它们。

因此,除了apply 存在问题外,您似乎对numpy 数组维度以及它们如何控制concatenate(以及各种stack 变体)的使用感到不满意。

【讨论】:

    猜你喜欢
    • 2010-09-29
    • 1970-01-01
    • 2021-11-30
    • 2018-03-10
    • 2015-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多