Python 两个列表性能的指数
Python exponentiation of two lists performance
有没有办法在 Python 中更快地计算 Cobb-Douglas utility function。我 运行 它数百万次,所以提高速度会有所帮助。该函数对 quantities_list 的元素进行指数列表对应元素的幂运算,然后将所有结果元素相乘。
n = 10
quantities = range(n)
exponents = range(n)
def Cobb_Douglas(quantities_list, exponents_list):
number_of_variables = len(quantities_list)
value = 1
for variable in xrange(number_of_variables):
value *= quantities_list[variable] ** exponents_list[variable]
return value
t0 = time.time()
for i in xrange(100000):
Cobb_Douglas(quantities, exponents)
t1 = time.time()
print t1-t0
迭代器是你的朋友。通过将你的循环切换到这个,我在我的计算机上获得了 28% 的加速:
for q, e in itertools.izip(quantities_list, exponents_list):
value *= q ** e
将循环切换到 functools.reduce
调用时我也得到了类似的结果,因此不值得提供代码示例。
一般来说,numpy
是快速算术运算的正确选择,但是 numpy
的最大整数类型是 64 位,它不会保存您的示例的结果。如果您使用不同的数值范围或算术类型,numpy
为王:
quantities = np.array(quantities, dtype=np.int64)
exponents = np.array(exponents, dtype=np.int64)
def Cobb_Douglas(quantities_list, exponents_list):
return np.product(np.power(quantities_list, exponents_list))
# result: 2649120435010011136
# actual: 21577941222941856209168026828800000
几个建议:
使用 Numpy
矢量化您的代码
如果数量很大,并且没有任何东西会是零或负数,则在 log-space 中工作。
我在本地使用了大约 15% 的加速:
def np_Cobb_Douglas(quantities_list, exponents_list):
return np.product(np.power(quantities_list, exponents_list))
大约 40% 使用:
def np_log_Cobb_Douglas(quantities_list, exponents_list):
return np.exp(np.dot(np.log(quantities_list), np.log(exponents_list)))
最后但同样重要的是,应该对您的 Cobb-Douglas 参数进行一些缩放,这样您就不会 运行 出现溢出错误(如果我没记错我的介绍宏的话)。
有没有办法在 Python 中更快地计算 Cobb-Douglas utility function。我 运行 它数百万次,所以提高速度会有所帮助。该函数对 quantities_list 的元素进行指数列表对应元素的幂运算,然后将所有结果元素相乘。
n = 10
quantities = range(n)
exponents = range(n)
def Cobb_Douglas(quantities_list, exponents_list):
number_of_variables = len(quantities_list)
value = 1
for variable in xrange(number_of_variables):
value *= quantities_list[variable] ** exponents_list[variable]
return value
t0 = time.time()
for i in xrange(100000):
Cobb_Douglas(quantities, exponents)
t1 = time.time()
print t1-t0
迭代器是你的朋友。通过将你的循环切换到这个,我在我的计算机上获得了 28% 的加速:
for q, e in itertools.izip(quantities_list, exponents_list):
value *= q ** e
将循环切换到 functools.reduce
调用时我也得到了类似的结果,因此不值得提供代码示例。
一般来说,numpy
是快速算术运算的正确选择,但是 numpy
的最大整数类型是 64 位,它不会保存您的示例的结果。如果您使用不同的数值范围或算术类型,numpy
为王:
quantities = np.array(quantities, dtype=np.int64)
exponents = np.array(exponents, dtype=np.int64)
def Cobb_Douglas(quantities_list, exponents_list):
return np.product(np.power(quantities_list, exponents_list))
# result: 2649120435010011136
# actual: 21577941222941856209168026828800000
几个建议:
使用 Numpy
矢量化您的代码
如果数量很大,并且没有任何东西会是零或负数,则在 log-space 中工作。
我在本地使用了大约 15% 的加速:
def np_Cobb_Douglas(quantities_list, exponents_list):
return np.product(np.power(quantities_list, exponents_list))
大约 40% 使用:
def np_log_Cobb_Douglas(quantities_list, exponents_list):
return np.exp(np.dot(np.log(quantities_list), np.log(exponents_list)))
最后但同样重要的是,应该对您的 Cobb-Douglas 参数进行一些缩放,这样您就不会 运行 出现溢出错误(如果我没记错我的介绍宏的话)。