根据更改阈值过滤np数组中值的最快方法

时间:2015-11-17 12:30:39

标签: python arrays numpy

我想根据某些阈值过滤数组arr

arr = np.array([2,2,2,2,2,5,5,5,1])
thresholds = np.array([4,1])

arr中的值大于阈值时,我想根据thresholds中的值过滤arr

我的想法是为每个阈值创建一个掩码

预期结果:

# [[False False False False False  True  True  True False]
#  [ True  True  True  True  True  True  True  True False]]

在Python中实现它的一种方法:

mask = [True if x>condi else False for condi in thresholds for x in arr]
mask = np.reshape(mask,(2,9))

然后只需filteredarr = arr[mask[i]]获取过滤后的数组,其中i是相关阈值的索引

在Python中有没有更好的方法(性能明智)?特别是我正在处理大数组(对于arr来说len约为250000,对于thresholds还没有特定的len,但是我期待一个大数组)?

修改 数据预期的最终输出为[array([5, 5, 5]), array([2, 2, 2, 2, 2, 5, 5, 5])]

1 个答案:

答案 0 :(得分:3)

使用

可以轻松获得蒙版
mask = arr[None,:]>thresholds[:,None]
mask

# Output
# array([[False, False, False, False, False,  True,  True,  True, False],
#        [ True,  True,  True,  True,  True,  True,  True,  True, False]], dtype=bool)

我们的想法是通过使用None(与np.newaxis相同)添加一个额外的轴来夸大维度,然后逐个元素地比较数组。

一旦我们有了掩码,我们就可以使用各种方法过滤数据,其中选择很大程度上取决于您的问题:

  • 当然可以

    res = [arr[m] for m in mask]
    # [array([5, 5, 5]), array([2, 2, 2, 2, 2, 5, 5, 5])]
    

    为了获得包含过滤数据的列表,但一般来说速度很慢。

  • 如果您有进一步的数值计算,我会创建一个masked array,其中只考虑过滤后的数据:

    m = np.zeros_like(mask).astype(np.int)
    m[:] = arr
    res = np.ma.masked_where(~mask,m)
    

    每行根据相应的阈值对应于过滤的数据。 屏蔽数组允许您继续使用许多功能,例如meanstd

    res.mean(axis=1)
    # masked_array(data = [5.0 3.125],
    #             mask = [False False],
    #       fill_value = 1e+20)
    
    res.mean(axis=1).compressed()
    # array([ 5.   ,  3.125])