Mic*_*ael 6 python performance numpy vectorization scipy
假设我有一个 nxm 矩阵并想fct对其每个元素调用一个函数。我可以这样做:
A = numpy.array(...)
vec_func = numpy.vectorize(fct)
A_out = vec_func(A)
Run Code Online (Sandbox Code Playgroud)
这将严格地将函数应用于每个矩阵元素,fct 将是一个函数:
def fct(a_ij):
# do something with matrix element a(i, j)
Run Code Online (Sandbox Code Playgroud)
现在我想要同样的,但是对于矩阵的每一行:
def fct(row_i):
# do something with matrix row(i)
Run Code Online (Sandbox Code Playgroud)
有没有办法做到这一点numpy.vectorize或类似?
编辑:看起来就像np.apply_along_axis你想要的那样。例如:
import numpy as np
def f(x):
return x * x.sum()
X = np.arange(12).reshape(2, 2, 3)
np.apply_along_axis(f, -1, X)
# array([[[ 0, 3, 6],
# [ 36, 48, 60]],
#
# [[126, 147, 168],
# [270, 300, 330]]])
Run Code Online (Sandbox Code Playgroud)
下面我最初的回复中有关性能的注释仍然适用。
原始回复:
虽然没有内置的功能,但 Python 可以让您自己轻松定义这样的上下文管理器。例如:
import numpy as np
from contextlib import wraps
def row_vectorize(f):
@wraps(f)
def wrapped_f(X):
X = np.asarray(X)
rows = X.reshape(-1, X.shape[-1])
return np.reshape([f(row) for row in rows],
X.shape[:-1] + (-1,))
return wrapped_f
@row_vectorize
def func(row):
return row * row.sum()
Run Code Online (Sandbox Code Playgroud)
现在您可以在任何非零维度的数组上使用它:
>>> X_1D = np.arange(3)
>>> func(X_1D)
array([0, 3, 6])
>>> X_2D = np.arange(6).reshape(2, 3)
>>> func(X_2D)
array([[ 0, 3, 6],
[36, 48, 60]])
>>> X_3D = np.arange(12).reshape((2, 2, 3))
>>> func(X_3D)
array([[[ 0, 3, 6],
[ 36, 48, 60]],
[[126, 147, 168],
[270, 300, 330]]])
Run Code Online (Sandbox Code Playgroud)
在性能方面,np.vectorize正在做一些非常相似的事情。
如果您需要更快地循环跨数组应用的自定义函数,您通常可以根据 numpy 按元素运算和聚合运算构建您的方法;例如,这个函数完成与上面的行向量化函数相同的事情,但在大输入上会更快:
def func2(X):
return X * X.sum(-1, keepdims=True)
Run Code Online (Sandbox Code Playgroud)
如果您想要跨数组行应用更复杂的操作,并且循环的性能是瓶颈,那么最好的选择可能是使用numba或cython。
| 归档时间: |
|
| 查看次数: |
5043 次 |
| 最近记录: |