re-grid / re-me sh неструктурированные данные трехмерного массива в уже существующую сетку - PullRequest
2 голосов
/ 09 июля 2020

У меня есть карта значений для определенной c сетки:

X       Y       Z       Value
0.555   0.334   0.472   1.361
0.674   0.729   0.711   2.114
0.538   0.982   0.886   2.406
0.775   0.279   0.789   1.843
0.292   0.206   0.984   1.482

Я хотел бы преобразовать значения (используя тот же метод интерполяции) в уже существующую сетку:

X       Y       Z       NewValue    
0.721   0.824   0.974   
0.244   0.982   0.813   
0.239   0.288   0.961   
0.885   0.439   0.308   
0.344   0.006   0.554   

например, в 2D: новые значения:

X       Y       Value
0.429   0.714   1.142
0.583   0.826   1.409
0.309   0.872   1.182
0.563   0.096   0.659
0.924   0.947   1.872

старая, ранее существовавшая сетка:

X       Y   
0.595   0.928   
0.426   0.800   
0.974   0.527   
0.864   0.398   
0.915   0.816   

оранжевые точки будут преобразованы в новые синие точки.

введите описание изображения здесь

Заранее спасибо

Ответы [ 2 ]

0 голосов
/ 16 июля 2020

Хороший и простой способ интерполировать - использовать радиальные базисные функции. Он работает в 2-х и 3-х измерениях.

Если вы используете Python и устанавливаете несколько модулей, таких как numpy, scipy и matplotlib (или вместо Anaconda , он несет их все ), тогда реализация могла бы выглядеть так (корректность не проверена полностью).

import numpy as np
from scipy.interpolate import Rbf
import matplotlib
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import pandas as pd
import matplotlib.cm as cm


# data read from csv files
source = 'source.csv'
target = 'target.csv'

# create a pandas dataframe for each file
# pandas used here so that a huge dataset can be handled easily
df = pd.read_csv(source, names=['xs', 'ys', 'zs', 'ts'])
df1 = pd.read_csv(target, names=['xt', 'yt', 'zt'])

# convert the data to numbers
xs = df['xs'].values
ys = df['ys'].values
zs = df['zs'].values
ts = df['ts'].values

xt = df1['xt'].values
yt = df1['yt'].values
zt = df1['zt'].values

# create a radial basis function interpolant
# works in 2D and 3D
rbf = Rbf(xs, ys, zs, ts)

# evaluate the interpolated function at the new locations
T = rbf(xt, yt, zt)

# plot the result
fig = plt.figure(figsize=(12, 8))
ax = fig.add_subplot(111, projection='3d')

# plot the newly interpolated points (bigger dots)
ax.scatter(xt, yt, zt, c=T, cmap=cm.jet, vmin=1.3, vmax=2.4, s=300)

# plot the original data (smaller dots)
ax.scatter(xs, ys, zs, c=ts, cmap=cm.jet, vmin=1.3, vmax=2.4, s=100)

ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')

plt.show()

введите описание изображения здесь

0 голосов
/ 12 июля 2020

Хорошо, нашел.

Сначала нам нужно убедиться, что исходные точки и / или координаты совпадают.

Во-вторых,

import pandas
import numpy
import scipy

old_x = dfOld['X'].to_numpy()
old_y = dfOld['Y'].to_numpy()
old_z = dfOld['Z'].to_numpy()
oldValues = dfOld['Value'].to_numpy()

new_x = dfNew['x'].to_numpy()
new_y = dfNew['y'].to_numpy()
new_z = dfNew['z'].to_numpy()

dfLin = scipy.interpolate.griddata((old_x, old_y, old_z), oldValues, (new_x, new_y, new_z), method='linear')
dfNear = scipy.interpolate.griddata((old_x, old_y, old_z), oldValues, (new_x, new_y, new_z), method='nearest')
dfLin[numpy.isnan(dfLin)] = dfNear[numpy.isnan(dfLin)] 
final = np.concatenate([newGrid, dfLin], axis=1)
...