我有一个形状为(n,)
的函数数组和一个形状为(m, n)
的numpy矩阵。现在,我想将每个函数应用于矩阵中的相应列,即
matrix[:, i] = funcs[i](matrix[:, i])
我可以使用for
循环(请参见下面的示例)来执行此操作,但是通常不建议在numpy中使用for循环。我的问题是最快(最好是最优雅)的方法是什么?
import numpy as np
# Example of functions to apply to each row
funcs = np.array([np.vectorize(lambda x: x+1),
np.vectorize(lambda x: x-2),
np.vectorize(lambda x: x+3)])
# Initialise dummy matrix
matrix = np.random.rand(50, 3)
# Apply each function to each column
for i in range(funcs.shape[0]):
matrix[:, i] = funcs[i](matrix[:, i])
答案 0 :(得分:1)
对于具有许多行和几列的数组,简单的列迭代应该是时间有效的:
In [783]: funcs = [lambda x: x+1, lambda x: x+2, lambda x: x+3]
In [784]: arr = np.arange(12).reshape(4,3)
In [785]: for i in range(3):
...: arr[:,i] = funcs[i](arr[:,i])
...:
In [786]: arr
Out[786]:
array([[ 1, 3, 5],
[ 4, 6, 8],
[ 7, 9, 11],
[10, 12, 14]])
如果函数使用一维数组输入,则不需要np.vectorize
(np.vectorize
通常比普通迭代要慢。)此外,对于这样的迭代,也不需要包装函数列表在一个数组中。遍历列表更快。
索引迭代的变体:
In [787]: for f, col in zip(funcs, arr.T):
...: col[:] = f(col)
...:
In [788]: arr
Out[788]:
array([[ 2, 5, 8],
[ 5, 8, 11],
[ 8, 11, 14],
[11, 14, 17]])
我在这里使用arr.T
,因此迭代位于arr
的列上,而不是行上。
一般性观察:在复杂任务上进行几次迭代是非常好的numpy
风格。简单任务的许多迭代速度很慢,因此应尽可能在已编译的代码中执行。
答案 1 :(得分:1)
这里的循环很有效,因为循环中的工作很繁重。
可读的解决方案就是:
np.vectorize(apply)(funcs,matrix)