Как применить интерполяцию IDW с помощью python для построения 3D поверхности с помощью Plotly

#python #plotly #interpolation

#python #plotly #интерполяция

Вопрос:

У меня есть X, Y, Z, к которым я хочу применить интерполяцию IDW, чтобы построить их с помощью Plotly 3D surface

Исходные данные

 data_only = data[['X (UTM)', 'Y (UTM)', 'Z (m)']]
data_only

       X (UTM)  Y (UTM) Z (m)
0   722542.0    3386811 -2105
1   722542.0    3386811 -2136
2   722542.0    3386811 -2166
3   722542.0    3386811 -2194
4   722542.0    3386811 -2204
... ... ... ...
11262   724306.0    3415328 -2308
11263   724264.0    3415400 -2358
11264   724251.0    3415421 -2368
11265   724233.0    3415450 -2380
11266   724203.0    3415498 -2393
11267 rows × 3 columns
  

Я нашел этот код для выполнения интерполяции IDW по данным, аналогичным моим:

     #First section of the code: 
#DISTANCE FUNCTION
def distance(x1,y1,x2,y2):
    d=np.sqrt((x1-x2)**2 (y1-y2)**2)
    return d

#CREATING IDW FUNCTION
def idw_npoint(xz,yz,n_point,p):
    r=10 #block radius iteration distance
    nf=0
    while nf<=n_point: #will stop when np reaching at least n_point
        x_block=[]
        y_block=[]
        z_block=[]
        r  =10 # add 10 unit each iteration
        xr_min=xz-r
        xr_max=xz r
        yr_min=yz-r
        yr_max=yz r
        for i in range(len(x)):
            # condition to test if a point is within the block
            if ((x[i]>=xr_min and x[i]<=xr_max) and (y[i]>=yr_min and y[i]<=yr_max)):
                x_block.append(x[i])
                y_block.append(y[i])
                z_block.append(z[i])
        nf=len(x_block) #calculate number of point in the block
    
    #calculate weight based on distance and p value
    w_list=[]
    for j in range(len(x_block)):
        d=distance(xz,yz,x_block[j],y_block[j])
        if d>0:
            w=1/(d**p)
            w_list.append(w)
            z0=0
        else:
            w_list.append(0) #if meet this condition, it means d<=0, weight is set to 0
    
    #check if there is 0 in weight list
    w_check=0 in w_list
    if w_check==True:
        idx=w_list.index(0) # find index for weight=0
        z_idw=z_block[idx] # set the value to the current sample value
    else:
        wt=np.transpose(w_list)
        z_idw=np.dot(z_block,wt)/sum(w_list) # idw calculation using dot product
    return z_idw

#Second Section of the code
n=100 #number of interpolation point for x and y axis
x_min=min(x)
x_max=max(x)
y_min=min(y)
y_max=max(y)
w=x_max-x_min #width
h=y_max-y_min #length
wn=w/n #x interval
hn=h/n #y interval
#list to store interpolation point and elevation
y_init=y_min
x_init=x_min
x_idw_list=[]
y_idw_list=[]
z_head=[]
for i in range(n):
    xz=x_init wn*i
    yz=y_init hn*i
    y_idw_list.append(yz)
    x_idw_list.append(xz)
    z_idw_list=[]
    for j in range(n):
        xz=x_init wn*j
        z_idw=idw_npoint(xz,yz,5,1.5) #min. point=5, p=1.5
        z_idw_list.append(z_idw)
    z_head.append(z_idw_list)
  

Когда я запускаю приведенный выше код, я получаю эту ошибку:

 ---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-61-dffa5e1667c9> in <module>
     22     for j in range(n):
     23         xz=x_init wn*j
---> 24         z_idw=idw_npoint(xz,yz,5,1.5) #min. point=5, p=1.5
     25         z_idw_list.append(z_idw)
     26     z_head.append(z_idw_list)

<ipython-input-59-b5cb7b2947f5> in idw_npoint(xz, yz, n_point, p)
     19         for i in range(len(x)):
     20             # condition to test if a point is within the block
---> 21             if ((x[i]>=xr_min and x[i]<=xr_max) and (y[i]>=yr_min and y[i]<=yr_max)):
     22                 x_block.append(x[i])
     23                 y_block.append(y[i])

~Anaconda3libsite-packagespandascoreseries.py in __getitem__(self, key)
    869         key = com.apply_if_callable(key, self)
    870         try:
--> 871             result = self.index.get_value(self, key)
    872 
    873             if not is_scalar(result):

~Anaconda3libsite-packagespandascoreindexesbase.py in get_value(self, series, key)
   4403         k = self._convert_scalar_indexer(k, kind="getitem")
   4404         try:
-> 4405             return self._engine.get_value(s, k, tz=getattr(series.dtype, "tz", None))
   4406         except KeyError as e1:
   4407             if len(self) > 0 and (self.holds_integer() or self.is_boolean()):

pandas_libsindex.pyx in pandas._libs.index.IndexEngine.get_value()

pandas_libsindex.pyx in pandas._libs.index.IndexEngine.get_value()

pandas_libsindex.pyx in pandas._libs.index.IndexEngine.get_loc()

pandas_libshashtable_class_helper.pxi in pandas._libs.hashtable.Int64HashTable.get_item()

pandas_libshashtable_class_helper.pxi in pandas._libs.hashtable.Int64HashTable.get_item()

KeyError: 0
  

Пожалуйста, дайте мне знать, есть ли альтернативный способ применить интерполяцию IDW с помощью python.

Комментарии:

1. Пожалуйста, уточните, X и Y — это ваши образцы пространства, а Z — значение функции, правильно?

2. ** ptyshevs ** Да, X и Y являются образцами пробелов «Широта и долгота», Z — значение функции «Глубина».