我想制作一个矩阵,它的所有条目都是某个变量的函数x
。因此B(x)
将以N x N
快速的方式理想地提供输出。事实上,如果您愿意输入带有函数作为条目的矩阵,这是一项简单的任务。举个例子:
f1 = lambda x: 2*x
f2 = lambda x: x**2
B = lambda x : np.array([[f1(x),f2(x)],
[f2(x),f1(x)]])
这是幼稚的,因为它无法扩展到阵列很大且具有多种功能的场景。键入它需要很长时间才能解决一个问题。通常会创建一个空数组并使用两个 Python for 循环来计算给定条目的特定函数,然后将输出存放在数组中。然后返回数组。
上述方法的问题在于,每次调用该函数时,都会运行那些 for 循环。如果您想在x
值的数据集上运行该函数,这会使它变慢。我尝试使用 Sympy 的lambdfiy
函数创建一个静态可调用数组。对于它的评估x
似乎比纯 Python 中的 for 循环解决方案更快。然而,这远远超过了设置成本。有关详细信息,请参阅下面的代码。
有没有办法使用vectorize
Numpy 中的函数来加快速度?您能否找到比 for 循环版本更快的解决方案?
我也玩弄这个想法(或称其为梦想),人们可以评估 X 的整个数据集,而不是单独评估每个 x。就像在 Numpy 中广播一样。例如
# Naive
result1 = [np.sin(x) for x in X]
# vs
results2 = np.sin(X)
无论如何,这很牵强。这是我写的代码。请玩转大小,N
看看速度下降是多么令人着迷。澄清一下,我已经对我的程序进行了整体评估,而这个可调用数组的问题正是瓶颈所在。
import numpy as np
from sympy import symbols,lambdify,zeros
from time import time
def get_sympy(N):
'''
Creates a callable array using Sympys lambdfiy capabilites.
This is truly a callable array.
'''
x = symbols('x')
output = zeros(N,N)
for i in range(N):
for j in range(N):
if i == j:
output[i,j] = x**2
elif i == 1:
output[i,j] = x**3
elif j == 0:
output[i,j] = x**4
else:
output[i,j] = x
return lambdify(x,output,'numpy')
def get_python(x,N):
'''
Uses Python loops to setup an array that mimic that of a callable array.
It is not truly a callable array as the loops run on each call of
this function.
'''
output = np.zeros((N,N))
f1 = lambda x: x**2
f2 = lambda x: x**3
f3 = lambda x: x**4
for i in range(N):
for j in range(N):
if i == j:
output[i,j] = f1(x)
elif i == 1:
output[i,j] = f2(x)
elif j == 0:
output[i,j] = f3(x)
else:
output[i,j] = x
return output
if __name__ == '__main__':
N = 30
X = np.random.uniform()
callable_sympy_array = get_sympy(N)
callable_python_array = lambda x: get_python(x,N)
t1 = time()
sympy_result = callable_sympy_array(X)
t2 = time()
python_result = callable_python_array(X)
t3 = time()
sympy_func = get_sympy(N)
t4 = time()
sympy_time = t2-t1
python_time = t3-t2
sympy_setup_time = t4-t3
print('\nSingle Evaluation Results:\n')
print('Sympy: ',round(sympy_time,5))
print('Python: ',round(python_time,5))
print('Sympy + Setup',round(sympy_setup_time,5))
evals = 100
print('\nResults for {0} evaluations of a {1} by {1} array:\n'.format(evals,N))
print('Sympy: ',sympy_setup_time + evals*sympy_time)
print('Python: ',python_time*evals)