scipy.interpolate.LinearNDInterpolator бесконечно зависает на больших наборах данных
Я интерполирую некоторые данные в Python, чтобы преобразовать их в обычный меш, чтобы я мог частично интегрировать их. Данные представляют функцию пространства параметров высокой размерности (в настоящее время 3, которое должно быть расширено по меньшей мере до 5) и возвращает многозначную функцию наблюдаемых (в настоящее время 2, которое должно быть расширено до 3, а затем потенциально десятки).
Я выполняю интерполяцию через scipy.interpolate.LinearNDInterpolator
из-за отсутствия каких-либо других очевидных вариантов (и потому что я понимаю, griddata
просто все равно это называет). На небольшом наборе данных (15 000 строк столбцовых данных) все работает хорошо. На больших наборах (60 000+) команда выполняется бесконечно долго. top
указывает, что iPython использует 100% ЦП, и терминал полностью не отвечает, в том числе C-c
, До сих пор я оставил это несколько часов безрезультатно, и в конечном итоге я хотел бы пропустить несколько миллионов записей.
Я подозреваю, что проблема связана с этим тикетом, но якобы он был исправлен в SciPy 0.10.0, который я обновил вчера.
Мой вопрос в основном, как мне выполнить многомерную интерполяцию для больших наборов данных? Исходя из того, что я попробовал, есть несколько возможных мест, из которых может прийти решение, но мне не повезло найти их. (Моему поиску не помогает тот факт, что некоторые из поддоменов Сципи, похоже, не работают...)
- Что не так с
LinearNDInterpolator
? Или, по крайней мере, как я могу выяснить, в чем проблема и попытаться обойти повешение? - Есть ли способ переформулировать интерполяцию так, чтобы
LinearNDInterpolator
буду работать? Может быть, рассудив данные осторожно, чтобы разделить их на части? - Существуют ли другие высокоразмерные интерполяторы, которые лучше подходят для этой проблемы? (Я отмечаю, что большинство альтернатив SciPy ограничены <пространством параметров 2D.)
- Существуют ли другие способы получения многомерных данных в обычную пользовательскую сетку? Это все, что я пытаюсь сделать, интерполируя...
1 ответ
Скорее всего, проблема в том, что ваш набор данных слишком велик, поэтому вычисление его триангуляции Делоне не завершится в разумные сроки. Проверьте масштабирование времени scipy.spatial.Delaunay
используя меньшие подмножества данных, случайно выбранные из вашего полного набора данных, чтобы оценить, завершится ли вычисление полного набора данных до окончания юниверса.
Если ваши исходные данные находятся на прямоугольной сетке, такой как
v[i,j,k,l] = f(x[i], y[j], z[k], u[l])
тогда использование основанной на триангуляции интерполяции очень неэффективно. Лучше использовать интерполяцию тензорного произведения, то есть последовательно интерполировать каждое измерение методом 1-D интерполяции:
import numpy as np
from scipy.interpolate import interp1d
def interp3(x, y, z, v, xi, yi, zi, method='cubic'):
"""Interpolation on 3-D. x, y, xi, yi should be 1-D
and z.shape == (len(x), len(y), len(z))"""
q = (x, y, z)
qi = (xi, yi, zi)
for j in range(3):
v = interp1d(q[j], v, axis=j, kind=method)(qi[j])
return v
def somefunc(x, y, z):
return x**2 + y**2 - z**2 + x*y*z
# some input data
x = np.linspace(0, 1, 5)
y = np.linspace(0, 2, 6)
z = np.linspace(0, 3, 7)
v = somefunc(x[:,None,None], y[None,:,None], z[None,None,:])
# interpolate
xi = np.linspace(0, 1, 45)
yi = np.linspace(0, 2, 46)
zi = np.linspace(0, 3, 47)
vi = interp3(x, y, z, v, xi, yi, zi)
import matplotlib.pyplot as plt
plt.subplot(121)
plt.pcolor(xi, yi, vi[:,:,12])
plt.title('interpolated')
plt.subplot(122)
plt.pcolor(xi, yi, somefunc(xi[:,None], yi[None,:], zi[12]))
plt.title('exact')
plt.show()
Если ваш набор данных разбросан и слишком велик для триангуляционных методов, вам нужно переключиться на другой метод. Некоторые опции - это методы интерполяции, работающие с небольшим количеством ближайших соседей одновременно (эту информацию можно быстро получить с помощью kd-дерева). Взвешивание с обратным расстоянием является одним из них, но оно может быть одним из худших - возможны лучшие варианты (которые я не знаю без дальнейших исследований).