【问题标题】:How can I run a numpy function percentile() on a masked array?如何在掩码数组上运行 numpy 函数 percentile()?
【发布时间】:2016-06-21 05:03:49
【问题描述】:

我尝试从具有 NoData 值的数组中检索百分位数。在我的例子中,Nodata 值由 -3.40282347e+38 表示。我认为掩码数组会将这些值排除在进一步的计算之外。我成功创建了掩码数组,但对于 np.percentile() 函数,掩码无效。

>>> DataArray = np.array(data)
>>> DataArray

([[ value, value...]], dtype=float32)

>>> masked_data = ma.masked_where(DataArray < 0, DataArray)
>>> p5 = np.percentile(masked_data, 5)
>>> print p5

 -3.40282347e+38

【问题讨论】:

  • 最好使用掩码方法或 np.ma 函数。许多 np 函数委托给方法,但不要指望它

标签: python arrays numpy


【解决方案1】:

如果您将掩码值填写为np.nan,则可以使用np.nanpercentile

import numpy as np
data = np.arange(-5.5,10.5) # Note that you need a non-integer array to store NaN
mdata = np.ma.masked_where(data < 0, data)
mdata = np.ma.filled(mdata, np.nan)
np.nanpercentile(mdata, 50) # 50th percentile

【讨论】:

  • 这当然是一个方便的解决方案(例如,它允许在特定的 axis 上应用百分位数,而简单地调用 mdata.compressed() 则不能),但我担心它很昂贵。跨度>
【解决方案2】:

查看np.percentile 代码,很明显它对掩码数组没有什么特别之处。

def percentile(a, q, axis=None, out=None,
               overwrite_input=False, interpolation='linear', keepdims=False):
    q = array(q, dtype=np.float64, copy=True)
    r, k = _ureduce(a, func=_percentile, q=q, axis=axis, out=out,
                    overwrite_input=overwrite_input,
                    interpolation=interpolation)
    if keepdims:
        if q.ndim == 0:
            return r.reshape(k)
        else:
            return r.reshape([len(q)] + k)
    else:
        return r

其中_ureduce_percentile 是在numpy/lib/function_base.py 中定义的内部函数。所以真正的动作比较复杂。

掩码数组有两种使用 numpy 函数的策略。一种是fill - 用无害的值替换掩码值,例如求和时为 0,求积时为 1。另一种是compress数据——即删除所有被屏蔽的值。

例如:

In [997]: data=np.arange(-5,10)
In [998]: mdata=np.ma.masked_where(data<0,data)

In [1001]: np.ma.filled(mdata,0)
Out[1001]: array([0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

In [1002]: np.ma.filled(mdata,1)
Out[1002]: array([1, 1, 1, 1, 1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

In [1008]: mdata.compressed()
Out[1008]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

哪个会给你想要的percentile?填充还是压缩?或者没有。您需要充分了解百分位数的概念,才能知道它应该如何应用于您的掩码值。

【讨论】:

  • Compressed() 为我解决了问题。因为我需要在百分位数计算之前完全排除 NoData 值。
猜你喜欢
  • 2020-02-29
  • 2017-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多