我正在将一些函数应用于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中有一些返回可迭代项(例如,可变长度列表)。
如何应用以这种方式返回多个值的函数(地图+ 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.vstack
,np.hstack
答案 0 :(得分: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
这样的2d输入仅是一种符号上的方便。对于较大的尺寸,便利性更大。但这并不能通过更直接的迭代来提高速度。
如果您不了解apply_along_axis
或在使用它时遇到问题,请不要打扰。进行您了解的那种迭代。
====
如果
def F_a(x):
return [1]
您的列表图将产生(5,1)和(5,2)数组,然后可以将它们连接在第二轴上。
因此,除了apply
遇到问题外,您似乎对numpy
数组维及其如何控制concatenate
(以及各种{{1 }}变体。