【发布时间】:2020-06-18 09:18:14
【问题描述】:
我正在使用 Python 为工程模拟生成输入数据。我需要定义某个物理量(我们称之为力)如何随时间变化。
力取决于一个已知的随时间变化的量(我们称之为角度)。对于每个时间步,力和角度之间的依赖关系是不同的。每个时间步的力角依赖性被定义为数据点,而不是函数。对于每个时间步,我需要从该时间步的力角依赖性中插入力的值。我在列表理解中使用scipy.interpolate.interp1d。
但是,我对表现不满意。插值循环需要将近 20 秒,速度慢得让人无法接受。时间步数约为 250k。力角相关性中的数据点数约为 2k。我尝试改用for 循环,但这更慢。
如何提高性能?如果可能,执行时间需要少于一秒。这里的代码不包含我使用的实际数据,但足够相似。
import numpy as np
import random
from scipy.interpolate import interp1d
import time
nTimeSteps = 250000
nPoints_forceAngleDependency = 2000
# Generating an example (bogus data)
angle = np.linspace(0., 2*np.pi, nPoints_forceAngleDependency)
forceAngleDependency_forEachTimeStep = [random.random() * np.sin(angle) for i in range(nTimeSteps)]
angleHistory = [random.random() * 2 * np.pi for i in range(nTimeSteps)]
# Interpolation
start = time.time()
forceHistory = [interp1d(angle, forceAngleDependency_forEachTimeStep[i])(angleHistory[i]) \
for i in range(nTimeSteps)]
end = time.time()
print 'interpolation duration: %s s' % (end - start)
【问题讨论】:
-
在不到 1 秒的时间内有 250k 个时间步长,这意味着每个时间步长应该持续不到 4e-6 秒,这对于顺序解释的 Python 代码来说是相当小的。关于点数,也意味着2ns/点的计算速度。此外,这里很难使用并行性,因为必须执行慢速(内核间或进程间)通信(可能在每个时间步)。
标签: python performance scipy scientific-computing