16

在 Numpy 1.4.1 中,计算掩码数组的直方图最简单或最有效的方法是什么? numpy.histogram并且pyplot.hist默认情况下计算被屏蔽的元素!

我现在能想到的唯一简单的解决方案是创建一个具有非屏蔽值的新数组:

histogram(m_arr[~m_arr.mask])

但是,这不是很有效,因为这不必要地创建了一个新数组。我很乐意阅读更好的想法!

4

4 回答 4

16

(根据上面的讨论取消删除...)

我不确定 numpy 开发人员是否会认为这是一个错误或预期的行为。我在邮件列表上问过,所以我想我们会看看他们怎么说。

无论哪种方式,这都很容易解决。修补numpy/lib/function_base.py使用numpy.asanyarray而不是numpy.asarray函数的输入将允许它正确使用掩码数组(或 ndarray 的任何其他子类)而无需创建副本。

编辑:这似乎是预期的行为。 正如这里所讨论的

如果你想忽略屏蔽数据,它只是额外的函数调用

直方图(m_arr.compressed())

我不认为这会产生额外的副本这一事实是相关的,因为我猜直方图中的全屏蔽数组处理会更加昂贵。

使用 asanyarray 还将允许直方图计算可能无法正确处理的矩阵和其他子类型。

正如布鲁斯指出的那样,除了删除蒙面观察之外,还有必要弄清楚直方图的蒙面数组定义是什么。

于 2010-09-02T20:08:56.393 回答
9

试试hist(m_arr.compressed())

于 2010-09-02T04:56:29.313 回答
6

这是一个非常古老的问题,但这些天我只使用:

numpy.histogram(m_arr, bins=.., range=.., density=False, weights=m_arr_mask)

其中 m_arr_mask 是一个与 m_arr 形状相同的数组,由要从直方图中排除的 m_arr 元素的 0 个值和要包含的元素的 1 个值组成。

于 2016-02-26T21:12:13.283 回答
0

通过尝试 Erik 的解决方案(请参阅https://github.com/numpy/numpy/issues/16616)遇到铸造问题后,我决定编写一个 numba 函数来实现此行为。

一些代码的灵感来自https://numba.pydata.org/numba-examples/examples/density_estimation/histogram/results.html。我加了mask一点。

import numpy
import numba  

@numba.jit(nopython=True)
def compute_bin(x, bin_edges):
    # assuming uniform bins for now
    n = bin_edges.shape[0] - 1
    a_min = bin_edges[0]
    a_max = bin_edges[-1]

    # special case to mirror NumPy behavior for last bin
    if x == a_max:
        return n - 1  # a_max always in last bin

    bin = int(n * (x - a_min) / (a_max - a_min))

    if bin < 0 or bin >= n:
        return None
    else:
        return bin


@numba.jit(nopython=True)
def masked_histogram(img, bin_edges, mask):
    hist = numpy.zeros(len(bin_edges) - 1, dtype=numpy.intp)

    for i, value in enumerate(img.flat):
        if mask.flat[i]:
            bin = compute_bin(value, bin_edges)
            if bin is not None:
                hist[int(bin)] += 1
    return hist  # , bin_edges

加速是显着的。在 (1000, 1000) 图像上:

在此处输入图像描述

于 2020-06-16T12:46:04.373 回答