Низкая производительность с использованием scipy.interpolate внутри цикла - PullRequest
1 голос
/ 18 июня 2020

Я использую Python для генерации входных данных для инженерного моделирования. Мне нужно определить, как определенная физическая величина (назовем ее силой) изменяется со временем.

Сила зависит от известной изменяющейся во времени величины (назовем ее углом). Зависимость между силой и углом разная для каждого временного шага. Зависимость сила-угол для каждого временного шага определяется как точки данных, а не как функция. Для каждого временного шага мне нужно интерполировать значение силы из зависимости силы от угла этого временного шага. Я использую scipy.interpolate.interp1d в понимании списка.

Однако я недоволен производительностью. Интерполяция l oop занимает почти 20 секунд, что недопустимо медленно. Количество временных шагов примерно 250к. Количество точек данных в зависимости сила-угол составляет примерно 2k. Я попытался использовать вместо него for l oop, но это было еще медленнее.

Как я могу улучшить производительность? По возможности время выполнения должно быть меньше секунды. Код здесь не содержит фактических данных, которые я использую, но достаточно похож.

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 Ответ

0 голосов
/ 18 июня 2020
  1. Используйте np.random.random(size=nTineSteps) для генерации выборок

  2. Для линейной интерполяции используйте numpy.interp вместо interp1d. Для сплайновой интерполяции более высокого порядка используйте CubicSpline или make_interp_spline и используйте векторизованное вычисление.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...