Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/293.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python中的MATLAB风格的find()函数_Python_Matlab_Find - Fatal编程技术网

Python中的MATLAB风格的find()函数

Python中的MATLAB风格的find()函数,python,matlab,find,Python,Matlab,Find,在MATLAB中,很容易找到满足特定条件的值的索引: >> a = [1,2,3,1,2,3,1,2,3]; >> find(a > 2) % find the indecies where this condition is true [3, 6, 9] % (MATLAB uses 1-based indexing) >> a(find(a > 2)) % get the values at those locati

在MATLAB中,很容易找到满足特定条件的值的索引:

>> a = [1,2,3,1,2,3,1,2,3];
>> find(a > 2)     % find the indecies where this condition is true
[3, 6, 9]          % (MATLAB uses 1-based indexing)
>> a(find(a > 2))  % get the values at those locations
[3, 3, 3]
def indices(a, func):
    return [i for (i, val) in enumerate(a) if func(val)]

a = [1, 2, 3, 1, 2, 3, 1, 2, 3]

inds = indices(a, lambda x: x > 2)

>>> inds
[2, 5, 8]
在Python中实现这一点的最佳方法是什么

到目前为止,我已经得出以下结论。要仅获取值,请执行以下操作:

>>> a = [1,2,3,1,2,3,1,2,3]
>>> [val for val in a if val > 2]
[3, 3, 3]
但是如果我想要这些值的索引,它就有点复杂了:

>>> a = [1,2,3,1,2,3,1,2,3]
>>> inds = [i for (i, val) in enumerate(a) if val > 2]
>>> inds
[2, 5, 8]
>>> [val for (i, val) in enumerate(a) if i in inds]
[3, 3, 3]
在Python中是否有更好的方法来实现这一点,特别是在任意条件下(不仅仅是“val>2”)


我在NumPy中找到了相当于MATLAB“find”的函数,但我目前无法访问这些库。

在NumPy中,您有
其中

>> import numpy as np
>> x = np.random.randint(0, 20, 10)
>> x
array([14, 13,  1, 15,  8,  0, 17, 11, 19, 13])
>> np.where(x > 10)
(array([0, 1, 3, 6, 7, 8, 9], dtype=int64),)

您可以创建一个函数,该函数接受一个可调用的参数,该参数将用于列表的条件部分。然后可以使用函数或其他函数对象传递任意条件:

>> a = [1,2,3,1,2,3,1,2,3];
>> find(a > 2)     % find the indecies where this condition is true
[3, 6, 9]          % (MATLAB uses 1-based indexing)
>> a(find(a > 2))  % get the values at those locations
[3, 3, 3]
def indices(a, func):
    return [i for (i, val) in enumerate(a) if func(val)]

a = [1, 2, 3, 1, 2, 3, 1, 2, 3]

inds = indices(a, lambda x: x > 2)

>>> inds
[2, 5, 8]

它更接近于您的Matlab示例,而不必加载所有numpy。

要获取任意条件下的值,可以使用带有lambda函数的
filter()

>>> a = [1,2,3,1,2,3,1,2,3]
>>> filter(lambda x: x > 2, a)
[3, 3, 3]
import numpy as np
a    = np.array([1,2,3,4,5])
inds = np.nonzero(a>2)
a[inds] 
array([3, 4, 5])
获取索引的一种可能方法是使用
enumerate()
构建包含索引和值的元组,然后过滤:

>>> a = [1,2,3,1,2,3,1,2,3]
>>> aind = tuple(enumerate(a))
>>> print aind
((0, 1), (1, 2), (2, 3), (3, 1), (4, 2), (5, 3), (6, 1), (7, 2), (8, 3))
>>> filter(lambda x: x[1] > 2, aind)
((2, 3), (5, 3), (8, 3))
为什么不直接使用这个:

[i for i in range(len(a)) if a[i] > 2]
或者对于任意条件,为您的条件定义函数
f
,并执行以下操作:

[i for i in range(len(a)) if f(a[i])]

我一直在试图找到一种快速的方法来完成这件事,下面是我偶然发现的(使用numpy进行快速向量比较):

事实证明,这比:

inds = [i for (i, val) in enumerate(a) if val > 2]
在numpy数组中进行比较时,Python的速度似乎更快,并且/或者在仅仅检查事实而不是比较时,进行列表理解时,Python的速度更快

编辑:

我在重温我的代码时,发现了一种可能不太占用内存、速度更快、超级简洁的方法,可以在一行中完成这项工作:

inds = np.arange( len(a) )[ a < 2 ]
inds=np.arange(len(a))[a<2]

或使用numpy的非零函数:

>>> a = [1,2,3,1,2,3,1,2,3]
>>> filter(lambda x: x > 2, a)
[3, 3, 3]
import numpy as np
a    = np.array([1,2,3,4,5])
inds = np.nonzero(a>2)
a[inds] 
array([3, 4, 5])

Matlab的find代码有两个参数。约翰的代码解释了第一个论点,但没有解释第二个论点。例如,如果您想知道在索引中满足条件的位置:Mtlab的函数将是:

find(x>2,1)
使用John的代码,您只需在Indexs函数的末尾添加一个[x],其中x是您要查找的索引号

def indices(a, func):
    return [i for (i, val) in enumerate(a) if func(val)]

a = [1, 2, 3, 1, 2, 3, 1, 2, 3]

inds = indices(a, lambda x: x > 2)[0] #[0] being the 2nd matlab argument

返回>>>2,第一个超过2的索引。

此应用程序更常用的
numpy
例程是;不过,我相信它的工作原理与

要获取这些值,您可以存储索引并使用它们进行切片:

a[inds]
也可以将数组作为可选参数传递:

numpy.where(a>2, a)
或多个阵列:

b = numpy.array([11,22,33,44,55])
numpy.where(a>2, a, b)

我想我可能已经找到了一个简单快捷的替代品。 顺便说一句,我觉得np.where()函数不是很令人满意,从某种意义上说,它包含了一行令人讨厌的零元素

import matplotlib.mlab as mlab
a = np.random.randn(1,5)
print a

>> [[ 1.36406736  1.45217257 -0.06896245  0.98429727 -0.59281957]]

idx = mlab.find(a<0)
print idx
type(idx)

>> [2 4]
>> np.ndarray
将matplotlib.mlab导入为mlab
a=np.random.randn(1,5)
打印
>> [[ 1.36406736  1.45217257 -0.06896245  0.98429727 -0.59281957]]
idx=mlab.find(a>[2 4]
>>np.ndarray
最好的,
Da

您的最后一个示例可以是
[a[i]代表inds中的i]
,这稍微简单一些。+1您还可以提到,您可以使用布尔数组对numpy数组进行索引,就像在matlab中一样。(例如
x[x>3]
而不是
np.where(x>3)
)(并不是说
where
有什么问题!对于熟悉Matlab的人来说,直接索引可能只是一种更为熟悉的形式。)这是一个好方法,但询问者指定他或她不能使用numpy。@JasonFruit,你是对的。我在阅读问题时没有理解。我被OP想要找到matlab函数的等价物的想法蒙蔽了双眼(而且matlab也很大)。顺便问一下,在哪种情况下您不能访问numpy?我唯一能看到的是您的老板是否不允许您使用它,或者您使用的是一种奇怪的操作系统或体系结构。它看起来像
,其中
实际返回索引,至少在版本1.6.1中是这样。如果您将其指定为第二个参数,它可以返回值。
a上的文档rgwhere
:“argwhere的输出不适用于索引数组。为此,请使用where(a)”。您可以使用
过滤器,但使用列表理解是首选的,而且更为优化。认为问题包含比此版本更好的代码:
inds=[i for(i,val)in enumerate(a)if val>2]
这是一种单线解决方案。