在Python3 / Numpy中过滤数组并返回索引

时间:2012-03-27 14:27:06

标签: python numpy python-3.x filtering

Python3 / Numpy中是否有内置函数过滤数组并返回剩余元素的索引?类似于numpy.argsort的东西用于排序。我的过滤器设置了最小和最大阈值 - 必须过滤掉低于/高于最小值/最大值的所有值。

我见过Python的函数filter,但我没有看到使用它提取索引的方法。

已编辑:答案中有很多有用的信息,谢谢!

正如@SvenMarnach所指出的那样,面具就足够了:

mask = (min_value < a) & (a < max_value)

现在我必须将此蒙版应用于与a形状相同的其他阵列,但不确定最佳方法是什么...

5 个答案:

答案 0 :(得分:5)

在您对其应用遮罩后,numpy.where will return the indices of an array命令。例如:

import numpy as np
A = np.array([1,2,3,6,2])
np.where(A>2)

给出:

(array([2, 3]),)

一个更复杂的例子:

A = np.arange(27).reshape(3,3,3)
np.where( (A>10) & (A<15) )

给出:

(array([1, 1, 1, 1]), array([0, 1, 1, 1]), array([2, 0, 1, 2]))

我同意@SvenMarnach,通常你不需要索引。

答案 1 :(得分:4)

您可以使用

获取一维数组a中大于min_value且小于max_value的元素的索引
indices = ((min_value < a) & (a < max_value)).nonzero()[0]

通常你不需要这些索引,但你可以使用掩码更有效地工作

mask = (min_value < a) & (a < max_value)

此蒙版是一个布尔数组,其形状与a相同。

修改:如果您有与b形状相同的数组a,则可以提取与{{1}对应的b元素True中带有

的条目
mask

答案 2 :(得分:3)

与您的问题没有直接关系,但filter()是一组三个函数的一部分,map()filter()reduce(),它们允许功能样式列表在Python中处理。

  • map(mapping_function, input_list)接受一个参数和一个列表的函数,依次将该函数应用于列表的每个元素,并返回一个输出列表作为结果。它或多或少等同于列表推导[mapping_function(item) for item in input_list]

  • filter(filter_function, input_list)会返回input_list返回filter_function True的元素列表。列表推导等效于[item for item in items if filter_function(item)]

  • reduce(combining_function, input_list)重复组合输入列表中的相邻元素对,直到只剩下一个值。例如,数字列表的总和可以表示为reduce(operator.add, numbers)

map()filter()的功能由Python中的列表推导提供(这就是mapfilter函数不经常使用的原因。)< / p>

reduce()是其中之一,并不表示自己是......任何东西的直观答案。编写一个循环几乎总是更清楚,这解释了为什么你不经常看到它。

答案 3 :(得分:1)

我很喜欢Sven的回答,事实上,正如Hooked提醒我的那样,numpy.where完全符合您的要求。但主要是因为我已经写出来了,这是另一种方法,只是为了说明一些技巧。 my_filter可以是返回与输入形状相同的布尔数组的任何函数:

def my_filter(a):
    return (10 < a) & (a < 40)

a_mask = my_filter(a)
indices = [ind[a_mask] for ind in numpy.indices(a.shape)]

例如:

>>> a = numpy.arange(100).reshape((10, 10))
>>> def my_filter(a):
...     return (min_value < a) & (a < max_value)
... 
>>> a_mask = my_filter(a)
>>> [ind[a_mask] for ind in numpy.indices(a.shape)]
[array([1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3,
       3, 3, 3, 3, 3, 3]), 
 array([1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3,
       4, 5, 6, 7, 8, 9])]

答案 4 :(得分:0)

您不一定需要numpy,可以通过简单的列表理解和enumerate来实现:

a = [1, 2, 3, 6, 2] 
[i for i, v in enumerate(a) if v < 2]

返回:

[2, 3]