沿着轴忽略nans的np.percentile的最佳方法是什么?

kef*_*ich 5 python numpy

np.percentile(ndarr, axis=0)对包含NaN值的数据有一个相当快速的方法吗?

因为np.median,相应的bottleneck.nanmedian(https://pypi.python.org/pypi/Bottleneck)非常好.

我提出的最好的百分位数是不完整的,目前是不正确的,是:

   from bottleneck import nanrankdata, nanmax, nanargmin
   def nanpercentile(x, q, axis):
       ranks = nanrankdata(x, axis=axis)
       peak = nanmax(ranks, axis=axis)
       pct = ranks/peak / 100. # to make a percentile
       wh = nanargmin(abs(pct-q),axis=axis)
       return x[wh]
Run Code Online (Sandbox Code Playgroud)

这不起作用; 真正需要的是采取第n个元素的一些方法axis,但我没有找到这样做的numpy切片技巧.

"合理快速"意味着比循环索引更好,例如:

q = 40
x = np.array([[[1,2,3],[6,np.nan,4]],[[0.5,2,1],[9,3,np.nan]]])
out = np.empty(x.shape[:-1])
for i in range(x.shape[0]):
   for j in range(x.shape[1]):
      d = x[i,j,:]
      out[i,j] = np.percentile(d[np.isfinite(d)], q)

print out

#array([[ 1.8,  4.8],
#       [ 0.9,  5.4]])
Run Code Online (Sandbox Code Playgroud)

哪个有效,但可能非常慢.

np.ma似乎没有按预期工作; 它将nan价值看作是inf:

xm = np.ma.masked_where(np.isnan(x),x)
print np.percentile(xm,40,axis=2)

# array([[ 1.8,  5.6],
#        [ 0.9,  7.8]])
Run Code Online (Sandbox Code Playgroud)