如何对 3D 阵列的部分进行切片和遮罩?

How do I slice and mask parts of a 3D array?

我使用 ma.masked_where 将此 3D 时间序列拆分为一个小区域,其中数据被屏蔽。 但是,它适用于 3D 阵列,而不仅仅是 2D。 我如何将相同的分析(拆分和屏蔽部分数据)应用于整个 3D 阵列,而不是仅应用于一个时间步长:

import numpy as np
import matplotlib.pyplot as plt
from numpy import ma

 # 3d data array
data = np.random.rand(5,45,60)

# taking only the 3rd time stamp (as an example) -- now 2d array
data1 = data[2,0:30,0:30]

x2, y2 = np.meshgrid(np.arange(0, 30, 1), np.arange(0, 30, 1))

data1 = ma.masked_where(x2 + y2 > 30, data1)
data2 = ma.masked_where(x2 + y2 < 10 , data1) #+
data3 = ma.masked_where(x2 + y2 > 25 , data2) #+
data4 = ma.masked_where(x2 - y2 > 10 , data3)
data5 = ma.masked_where(x2 - y2 < -5 , data4)

plt.contourf(data[2])
plt.xlim(0,60)
plt.ylim(0,45)
plt.show()

plt.contourf(data5)
plt.xlim(0,60)
plt.ylim(0,45)
plt.show()

# attempt at applying one part of the data mask to the 3d data array 
data1 = []


for i in range(5):
    data1.append(ma.masked_where(x2 + y2 > 30, data[i]))

data1 = np.array(data1)

我也试过这个...更接近了但是掩码没有复制到原始数组(现在重命名为 d):

d = np.random.rand(5,30,30)

mask = ma.array(data5)

print(mask.shape)
plt.contourf(mask)
plt.show()

#m = np.ma.masked_invalid(mask)
#print(m)

#test = ma.masked_where(np.ma.getmaskarray(mask),d)

x = []

for i in range(5):
        x.append(ma.masked_where(np.ma.getmaskarray(mask),d[i,:,:]))
x = np.array(x)

plt.contourf(x[2])

一种方法是将 x2y2 广播到形状 (5, 30, 30)。这允许它们在 ma.masked_where 中与数据的 3D 部分一起使用:

data1 = data[:, 0:30, 0:30]

x2, y2 = [np.broadcast_to(a, (5, 30, 30)) for a in np.meshgrid(np.arange(0, 30, 1), np.arange(0, 30, 1))]

除绘图外,其余代码可以保持不变。整个代码为:

import numpy as np
import matplotlib.pyplot as plt
from numpy import ma

# 3d data array
data = np.random.rand(5, 45, 60)

# now taking all time stamps -- now 3d array
data1 = data[:, 0:30, 0:30]

x2, y2 = [np.broadcast_to(a, (5, 30, 30)) for a in np.meshgrid(np.arange(0, 30, 1), np.arange(0, 30, 1))]



data1 = ma.masked_where(x2 + y2 > 30, data1)
data2 = ma.masked_where(x2 + y2 < 10, data1)  # +
data3 = ma.masked_where(x2 + y2 > 25, data2)  # +
data4 = ma.masked_where(x2 - y2 > 10, data3)
data5 = ma.masked_where(x2 - y2 < -5, data4)

plt.contourf(data[2])
plt.xlim(0, 60)
plt.ylim(0, 45)
plt.show()

for data5_i in data5:
    plt.contourf(data5_i)
    plt.xlim(0, 60)
    plt.ylim(0, 45)
    plt.show()