Интерполяция и экстраполяция случайно рассеянных данных в равномерную сетку в 3D

У меня есть сетка 256 x 256 x 32 с регулярно расположенными точками в диапазоне x, y и z и соответствующей переменной "a". У меня также есть группа случайно разбросанных точек в более узком пространстве x, y, z со связанной переменной "b". По сути, я хочу интерполировать и экстраполировать мои случайные данные на сетку с регулярным интервалом, которая соответствует кубу "а", как показано ниже:

Визуальное представление

До сих пор я использовал griddata scipy для достижения интерполяции, которая, кажется, работает нормально, но она не может справиться с экстраполяцией (насколько я знаю), и результат резко усекается до значений 'nan'. Во время исследования этой проблемы я столкнулся с парой людей, использующих griddata во второй раз с "ближайшим" в качестве метода интерполяции для заполнения значений "nan". Я пробовал это, но результаты не кажутся надежными. Более подходящие результаты получаются, если я использую fill_Value с "линейным" режимом, но на данный момент это больше помадка, потому что fill_Value должен быть константой.

Я заметил, что в MATLAB есть класс ScatteredInterpolant, который, кажется, делает то, что я хочу, но я не могу найти эквивалентный класс в Python или выяснить, как эффективно реализовать такую ​​процедуру в 3D. Любая помощь с благодарностью.

Код, который я использую для интерполяции, приведен ниже:

x, y, z, b = np.loadtxt(scatteredfile, unpack = True)

# Create cube to match aCube dimensions
xi = np.linspace(-xmax_aCube, xmax_aCube, 256)
yi = np.linspace(-ymax_aCube, ymax_aCube, 256)
zi = np.linspace(zmin_aCube, zmax_aCube, 32)

# Interpolate scattered points
X, Y, Z = np.meshgrid(xi, yi, zi)
bCube = griddata((x, y, z), b, (X, Y, Z), method = 'linear')    

2 ответа

Это обсуждение применимо в любой размерности. Для вашего трехмерного случая давайте сначала поговорим о вычислительной геометрии, чтобы понять, почему часть региона дает NaN от griddata,

Рассеянные точки в вашем объеме составляют выпуклый корпус; геометрическая форма со следующими свойствами:

  • Поверхность всегда выпуклая (как следует из названия)
  • Объем формы минимально возможен без нарушения выпуклости
  • Поверхность (в 3d) триангулирована и замкнута

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

В обычном месте сетки внутри воздушного шара вы окружены известными точками. Вы можете интерполировать в эти места. За пределами этого вы должны экстраполировать.

Экстраполяция это сложно. Там нет общего правила, как это сделать... это зависит от конкретной проблемы. В этом регионе алгоритмы, такие как griddata выбрать, чтобы вернуться NaN - это самый безопасный способ сообщить ученому, что он должен выбрать разумный способ экстраполяции.

Давайте рассмотрим несколько способов сделать это.

1. [WORST] Обманите это

Назначьте некоторое скалярное значение вне корпуса. В кратких документах вы увидите, что это делается с помощью: s = mean(b) bCube = griddata((x, y, z), b, (X, Y, Z), method = 'linear', fill_value=s)

Минусы: это приводит к резкому разрыву в интерполированном поле на границе корпуса, сильно смещает среднее значение скалярного поля и не учитывает функциональную форму данных.

2. [СЛЕДУЮЩИЙ МИР] "Смешанный дурак"

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

Извините, это псевдокод, поскольку я вообще не использую numpy, но, вероятно, это будет довольно ясно.

# With a unit cube, and selected scalar value
x, y, z, b = np.loadtxt(scatteredfile, unpack = True)
s = mean(b)
x.append([0 0 0 0 1 1 1 1])
y.append([0 0 1 1 0 0 1 1])
z.append([0 1 0 1 0 1 0 1])
b.append([s s s s s s s s])
# drop in the rest of your code

Минусы: это приводит к резкому разрыву градиента интерполированного поля на границе корпуса, довольно сильно смещает среднее значение скалярного поля и не учитывает функциональную форму данных.

3. [Все еще ПЛОХО ПЛОХО] Ближайший сосед

Для каждой из обычных точек NaN найдите ближайшее не-NaN и присвойте это значение. Это эффективно и стабильно, но грубо, потому что ваше поле может в конечном итоге иметь узорные элементы (например, полосы или лучи, выходящие из корпуса), часто визуально непривлекательные или, что еще хуже, неприемлемые с точки зрения гладкости данных

В зависимости от плотности данных вы можете использовать ближайшую рассеянную точку данных вместо ближайшей не-NaN регулярной точки. Это может быть сделано просто (опять же, псевдокод):

bCube = griddata((x, y, z), b, (X, Y, Z), method = 'linear', fill_value=nan)
bCubeNearest = griddata((x, y, z), b, (X, Y, Z), method = 'nearest')
indicesMask = isNan(bCube)
# Use nearest interpolation outside the hull, keeping linear interpolation inside.
bCube(indicesMask) = bCubeNearest(indicesMask)

Использование подходов MATLAB на основе delaunay покажет более мощные методы для достижения подобного в однострочнике, но здесь numpy выглядит немного ограниченным.

4. [НЕ ВСЕГДА УЖАСНО] Естественно взвешенный

Извините за плохое объяснение в этом разделе, я никогда не писал алгоритм, но я уверен, что некоторые исследования техники естественного соседа помогут вам далеко

Используйте функцию взвешивания расстояния с некоторым параметром D, который может быть примерно или вдвое больше (скажем) длины вашей коробки. Вы можете настроить. Для каждого местоположения NaN определите расстояние до каждой точки рассеяния.

# Don't do it this way for anything but small matrices - this is O(NM) 
# and it can be done much more effectively (e.g. MATLAB has a quick 
# natural weighting option), but for illustrative purposes:
for each NaN point 1:N
    for each scattered point 1:M
        calculate a basis function using inverse distance from NaN to point, normalised on D, and store in a [1 x M] vector of weights
Multiply weights by the b value, summate and divide by M   

В основном вы хотите получить функцию, которая плавно переходит к средней интенсивности B на расстоянии D от корпуса, но совпадает с оболочкой на границе. Вдали от границы он наиболее сильно взвешен в ближайших точках.

Плюсы: приятно стабильные и достаточно продолжительные. Из-за взвешивания более устойчив к шуму в отдельных точках данных, чем ближайший сосед.

5. [HEROIC ROCKSTAR] Допущение функциональной формы

Что вы знаете о физике? Предположим, что функциональная форма представляет то, что вы ожидаете от физики, затем выполните наименьшие квадраты (или какой-нибудь эквивалент) для подгонки этой формы к разбросанным данным. Используйте функцию для стабилизации экстраполяции.

Несколько хороших идей, которые могут помочь вам построить функцию:

  • Ожидаете ли вы симметрию или периодичность?
  • Является ли компонент ba векторного поля, обладающего некоторым свойством, например, нулевой дивергенцией?
  • Направленность: ожидаете ли вы, что все углы будут одинаковыми? Или, может быть, линейное изменение в одном направлении?
  • находится ли поле b в определенный момент времени - возможно, можно использовать сглаженную серию измерений, чтобы придумать основную функцию?
  • Существует ли уже известная форма, подобная гауссовой или квадратичной?

Некоторые примеры:

  • b представляет интенсивность лазерного луча, проходящего через объем. Вы ожидаете, что входная сторона будет номинально идентична выходной, а остальные четыре границы нулевой интенсивности. Интенсивность будет иметь концентрический гауссов профиль.

  • b является одной из составляющих поля скоростей в несжимаемой жидкости. Жидкость должна быть бездивергентной, поэтому любое месторождение в зоне NaN также должно быть бездивергентным, чтобы вы применили это условие.

  • б представляет температуру в комнате. Вы ожидаете более высокую температуру наверху, потому что горячий воздух поднимается.

  • b представляет подъемную силу на аэродинамической поверхности, проверенную по трем независимым переменным. Вы можете легко найти лифт в стойле, поэтому точно знайте, что будет в некоторых частях пространства.

Плюсы / минусы: поймите это правильно, и это будет здорово. Поймите это неправильно, особенно с нелинейными функциональными формами, и это пойдет очень неправильно и может привести к очень нестабильным результатам.

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

Если ваш разброс точек достаточно хорошо соответствует форме куба, одним из подходов может быть использование griddata интерполировать на регулярную сетку данных, которая вписывается в ваше облако точек (следовательно, избегая nans), а затем использовать эту регулярную сетку значений в качестве входных данных для interpn что облегчает линейную экстраполяцию (но требует регулярной сетки в качестве входных данных).

Таким образом, вы можете использовать griddata как и раньше для всех точек внутри выпуклой оболочки вашего разброса точек, и вы можете использовать interpn оценить точки, которые возвращаются как нанс.

Это далеко не идеально, но я думаю, что это ближе к достижению того, что вы ищете.

Плюсы:

  • Избегает резких разрывов.
  • Захватывает основные линейные тренды на границе вашего набора данных, не зная функциональной формы.
  • Учитывает асимметрию в ваших данных (например, не имеет тенденцию к значению совокупности на больших расстояниях, поэтому одна сторона вашего набора данных может иметь большие значения, чем другая на больших расстояниях.)

Минусы:

  • Эффективность этого подхода будет во многом зависеть от того, насколько большой куб вы можете поместить в выпуклую оболочку вашего первоначального разброса точек. Если ваши данные являются заостренными / неоднородными и нерегулярными, то даже точки на краю выпуклого корпуса могли быть экстраполированы на значительные расстояния от края вложенного куба, что приводило к ошибкам, поскольку при экстраполяции не учитывались более близкие точки данных, лежащие вне куба.
  • Линейная экстраполяция будет сильно зависеть от шума в данных на краях облака точек.
  • Вычислительная стоимость выполнения двух наборов интерполяций.
Другие вопросы по тегам