簡體   English   中英

在 Python 中插入 3D 數組

[英]Interpolate a 3D array in Python

我有一個 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 模塊,似乎有一些方法可以在一維和二維數組上執行此操作,但不像我需要的那樣是 3D - 盡管我可能錯過了一些東西。

使用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.]]

[編輯] 第一個提議的解決方案:

對此答案中的代碼進行一些修改:

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.]]]

只有當 NaN 都在同一個切片上時,它才能很好地工作。 存在孤立 NaN 的切片將被忽略。

從 xdze2 提供的評論和以前的答案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方法確保將其應用於 3D 數組。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM