代码之家  ›  专栏  ›  技术社区  ›  tda

在Python中插值三维数组

  •  2
  • tda  · 技术社区  · 6 年前

    我有一个3D NumPy数组,看起来像这样:

    arr = np.empty((4,4,5))
    arr[:] = np.nan
    arr[0] = 1
    arr[3] = 4
    
    arr
    >>> [[[ 1.  1.  1.  1.  1.]
          [ 1.  1.  1.  1.  1.]
          [ 1.  1.  1.  1.  1.]
          [ 1.  1.  1.  1.  1.]]
    
         [[ nan nan nan nan nan]
          [ nan nan nan nan nan]
          [ nan nan nan nan nan]
          [ nan nan nan nan nan]]
    
         [[ nan nan nan nan nan]
          [ nan nan nan nan nan]
          [ nan nan nan nan nan]
          [ nan nan nan nan nan]]
    
         [[ 4.  4.  4.  4.  4.]
          [ 4.  4.  4.  4.  4.]
          [ 4.  4.  4.  4.  4.]
          [ 4.  4.  4.  4.  4.]]]
    

    我想插一句 axis=0

    >>> [[[ 1.  1.  1.  1.  1.]
          [ 1.  1.  1.  1.  1.]
          [ 1.  1.  1.  1.  1.]
          [ 1.  1.  1.  1.  1.]]
    
         [[ 2.  2.  2.  2.  2.]
          [ 2.  2.  2.  2.  2.]
          [ 2.  2.  2.  2.  2.]
          [ 2.  2.  2.  2.  2.]]
    
         [[ 3.  3.  3.  3.  3.]
          [ 3.  3.  3.  3.  3.]
          [ 3.  3.  3.  3.  3.]
          [ 3.  3.  3.  3.  3.]]
    
         [[ 4.  4.  4.  4.  4.]
          [ 4.  4.  4.  4.  4.]
          [ 4.  4.  4.  4.  4.]
          [ 4.  4.  4.  4.  4.]]]
    

    我一直在研究SciPy模块,似乎有一些方法可以在1D和2D阵列上实现这一点,但不像我需要的3D,尽管我可能遗漏了一些东西。

    2 回复  |  直到 6 年前
        1
  •  2
  •   xdze2    6 年前

    使用 apply_along_axis :

    import numpy as np
    
    def pad(data):
        good = np.isfinite(data)
        interpolated = np.interp(np.arange(data.shape[0]),
                                 np.flatnonzero(good), 
                                 data[good])
        return interpolated
    
    
    arr = np.arange(6, dtype=float).reshape((3,2))
    arr[1, 1] = np.nan
    print(arr)
    
    new = np.apply_along_axis(pad, 0, arr)
    print(arr)
    print(new)
    

    [[ 0.  1.]
     [ 2. nan]
     [ 4.  5.]]
    
    [[ 0.  1.]
     [ 2. nan]
     [ 4.  5.]]
    
    [[0. 1.]
     [2. 3.]
     [4. 5.]]
    

    [编辑]第一个建议的解决方案:

    对源代码进行了一些修改 this answer

    import numpy as np
    from scipy import interpolate
    
    A = np.empty((4,4,5))
    A[:] = np.nan
    A[0] = 1
    A[3] = 4
    
    indexes = np.arange(A.shape[0])
    good = np.isfinite(A).all(axis=(1, 2)) 
    
    f = interpolate.interp1d(indexes[good], A[good],
                             bounds_error=False,
                             axis=0)
    
    B = f(indexes)
    print(B)
    

    给予:

    [[[1. 1. 1. 1. 1.]
      [1. 1. 1. 1. 1.]
      [1. 1. 1. 1. 1.]
      [1. 1. 1. 1. 1.]]
    
     [[2. 2. 2. 2. 2.]
      [2. 2. 2. 2. 2.]
      [2. 2. 2. 2. 2.]
      [2. 2. 2. 2. 2.]]
    
     [[3. 3. 3. 3. 3.]
      [3. 3. 3. 3. 3.]
      [3. 3. 3. 3. 3.]
      [3. 3. 3. 3. 3.]]
    
     [[4. 4. 4. 4. 4.]
      [4. 4. 4. 4. 4.]
      [4. 4. 4. 4. 4.]
      [4. 4. 4. 4. 4.]]]
    

        2
  •  0
  •   tda    6 年前

    根据xdze2和之前的 answer here ,我想到了这个:

    import numpy as np
    
    def pad(data):
        bad_indexes = np.isnan(data)
        good_indexes = np.logical_not(bad_indexes)
        good_data = data[good_indexes]
        interpolated = np.interp(bad_indexes.nonzero()[0], good_indexes.nonzero()[0], 
        good_data)
        data[bad_indexes] = interpolated
        return data
    
    arr = np.empty((4,4,5))
    arr[:] = np.nan
    
    arr[0] = 25
    arr[3] = 32.5
    
    # Apply the pad method to each 0 axis
    new = np.apply_along_axis(pad, 0, arr)
    

    “pad”方法基本上应用了插值和 np.apply_along_axis