我有一个形状(10, 100000)
和一个函数f
的数组,它将形状(100000,)
的数组转换为形状(200,200)
的数组。将f
应用于10行中的每一行以获得形状数组的最简单方法是什么
(10,200,200)
?我希望使用apply_along_axis
,但它似乎不起作用,因为f
的输出的维度高于输入的维度。
(更一般地说,给定形状a
的数组(x1,...,xn,y1,...,ym)
和函数f
,它将形状(y1,...,ym)
的数组转换为形状(z1,...,zp)
的数组,您可能希望将f
应用于m
的最后a
维度,对于n
的第一个a
维度的每个设置,以获取形状(x1,...,xn,z1,...,zp)
。或者你可能有一个问题可以转换成这种形式之一。做这些转换的最佳方法是什么?)
答案 0 :(得分:1)
我的第一个想法是重塑a
,将第一个n
尺寸折叠为一个。然后,只需迭代该维度,将f
应用于每个子阵列。将结果收集到列表(或正确大小的数组)中。最后重塑。
正如您所描述的那样,x1...xn
尺寸只是为了骑行。
查看apply_along_axis
的代码。它迭代所有轴,除了传递给函数的轴。它没有做任何你可以用你自己的迭代做的事情。它会处理x1...xn
上的迭代,但需要将y
维度折叠为1,并且需要一个返回相同形状的函数。
该功能的核心是
res = func1d(arr[tuple(i.tolist())], *args, **kwargs)
outarr[tuple(ind)] = res
其中outarr
已初始化为正确的大小,ind
会跨越所有维度(除了一个)。它有一个slice
对象res
。
=====================
以2d输入数组开头的简单示例:
In [933]: def foo(arr):
...: return arr.reshape(2,-1)
...:
In [934]: source=np.arange(12).reshape(3,4)
In [935]: dest=np.zeros((source.shape[0],2,2),source.dtype)
In [936]: for i,r in enumerate(source):
...: dest[i,...] = foo(r)
...:
In [937]: dest
Out[937]:
array([[[ 0, 1],
[ 2, 3]],
[[ 4, 5],
[ 6, 7]],
[[ 8, 9],
[10, 11]]])
因此,这将迭代源的行,生成新数组,并将它们插入到目标的正确位置。要设置目的地,我必须知道foo
生成的内容(维度)。
列表附加方法并不需要太多的知识:
In [938]: dest=[]
In [939]: for i,r in enumerate(source):
...: dest.append(foo(r))
In [940]: dest
Out[940]:
[array([[0, 1],
[2, 3]]), array([[4, 5],
[6, 7]]), array([[ 8, 9],
[10, 11]])]
In [941]: np.array(dest)
...
归结为旧问题,'如何从函数生成新数组?'