我有一个4D矩阵,A(形状[251,6,60,141])包含很多NaN。我想将这个矩阵重塑成另一个矩阵B(形状[73,6,60,141])。换句话说,在axis = 0中,我想采用不规则间隔步长的numpy.nanmean()。有效的方法吗?
我希望下面代码中的循环说明我的愿望,但我认为它不起作用,因为它以(似乎)无休止的RuntimeWarnings循环结束:
" /opt/anaconda3/lib/python3.4/site-packages/numpy/lib/nanfunctions.py:598:RuntimeWarning:空切片的平均值 warnings.warn("空切片的意思",RuntimeWarning)"
import numpy as np
A = np.full(([251,6,60,141]), np.nan) # Create matrix A full of NaNs
# Assign some random values in random grid boxes in A
A[0, 1, 2, 3] = 4
A[1, 2, 3, 4] = 5
A[2, 3, 4, 5] = 6
A[3, 4, 5, 6] = 7
# Create the 1D array of the number of rows I want to average together in each interval
intvl = [0, 5, 2, 2, 1, 6, 5, 4, 1, 6, 2, 2, 3, 2, 2, 5, 6, 3, 3, 3, 3, 3, 3, 3, 2, 6, 3, 6, 3, 1, 6, 3, 6, 1, 4, 6, 3, 3, 2, 2, 3, 4, 2, 5, 1, 3, 1, 3, 1, 6, 4, 2, 3, 5, 5, 5, 7, 4, 2, 3, 4, 3, 2, 3, 5, 3, 2, 7, 5, 3, 5, 3, 3, 2]
# Sum the intvl array stepwise
intvl_cs = np.cumsum(intvl)
# Loop to perform the interval summation
B = np.full(([len(intvl),6,60,141]), np.nan) # Create the matrix B, intially full of NaNs
for b in np.arange(len(intvl)-1):
for L in np.arange(6):
for i in np.arange(60):
for j in np.arange(141):
B[b,L,i,j] = np.nanmean(A[intvl_cs[b]:intvl_cs[b+1],L,i,j])
答案 0 :(得分:2)
为了提高性能,您可以在使用
替换整个循环块时对求和进行矢量化for b in np.arange(len(intvl)-1):
B[b, ...] = np.nanmean(A[intvl_cs[b]:intvl_cs[b+1], ...], axis=0)
如果你这样做,那就让它更具可读性
B = np.zeros((len(intvl_cs) - 1, 6, 60, 141))
# no need to initialize to `nan` if we are touching all values anyways
for b, (start, stop) in enumerate(zip(intvl_cs[:-1], intvl_cs[1:])):
B[b, ...] = np.nanmean(A[start:stop, ...], axis=0)
在我的机器上,计算在几分之一秒内完成。