查找大于 x 的元素的索引

Posted

技术标签:

【中文标题】查找大于 x 的元素的索引【英文标题】:Find the indices of elements greater than x 【发布时间】:2012-11-22 22:31:09 【问题描述】:

给定以下向量,

a = [1, 2, 3, 4, 5, 6, 7, 8, 9]

我需要识别元素大于 4 的“a”的索引,如下所示:

idx = [3, 4, 5, 6, 7, 8] 

“idx”中的信息将用于从另一个列表X中删除元素(X与“a”的元素数量相同):

del X[idx] #idx is used to delete these elements in X. But so far isn't working.

我听说 numpy 可能会有所帮助。有任何想法吗? 谢谢!

【问题讨论】:

循环是一个很好的起点。 您的 idx 示例是错误的,列表中只有 9 个元素,因此 9 个索引,0-8。跨度> 你的问题有点自相矛盾。看起来您可能将索引与元素混淆了(您的 idx 实际上是元素列表,而您正在询问索引列表)。另外请在询问之前告诉您您自己尝试过什么? @0xc0de 我想他/她只是在这里输入伪代码。 感谢您的所有回答。实际上我没有提到我需要使用 idx 作为索引来从另一个列表中删除元素,而不是... 【参考方案1】:

我想我来这里有点晚了(虽然使用 Numpy 变得更容易了)..

import numpy as np

# Create your array
a = np.arange(1, 10)
# a = array([1, 2, 3, 4, 5, 6, 7, 8, 9])

# Get the indexes/indices of elements greater than 4 
idx = np.where(a > 4)[0]
# idx = array([4, 5, 6, 7, 8])

# Get the elements of the array that are greater than 4
elts = a[a > 4]
# elts = array([5, 6, 7, 8, 9])

# Convert idx(or elts) to a list
idx = list(idx)
#idx = [4, 5, 6, 7, 8]

【讨论】:

【参考方案2】:

在我看来最简单的就是使用 numpy

X[np.array(a)>4]#X needs to be np.array as well

说明: np.array 将 a 转换为数组。

np.array(a)>4 给出一个 bool 数组,其中包含应保留的所有元素

并且 X 被 bool 数组过滤,因此只选择 a 大于 4 的元素(其余的被丢弃)

【讨论】:

【参考方案3】:

好的,我明白你的意思,一行 Python 就足够了:

使用列表理解

[ j for (i,j) in zip(a,x) if i >= 4 ]
# a will be the list compare to 4
# x another list with same length

Explanation:
>>> a
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> x
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j']

Zip 函数将返回一个元组列表

>>> zip(a,x)
[(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e'), (6, 'f'), (7, 'g'), (8, 'h'), (9, 'j')]

列表推导式是一种在“in”之后的列表上循环元素的快捷方式,并使用表达式评估元素,然后将结果返回到列表中,您也可以添加条件来返回要返回的结果

>>> [expression(element) for **element** in **list** if condition ]

这段代码什么也不做,只是返回所有压缩的对。

>>> [(i,j) for (i,j) in zip(a,x)]
[(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e'), (6, 'f'), (7, 'g'), (8, 'h'), (9, 'j')]

我们要做的是通过指定“if”后跟一个布尔表达式来添加一个条件

>>> [(i,j) for (i,j) in zip(a,x) if i >= 4]
[(4, 'd'), (5, 'e'), (6, 'f'), (7, 'g'), (8, 'h'), (9, 'j')]

使用 Itertools

>>> [ _ for _ in itertools.compress(d, map(lambda x: x>=4,a)) ]
# a will be the list compare to 4
# d another list with same length

在 Python 中使用带有 单行 的 itertools.compress 来完成关闭此任务

>>> a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> d = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j'] # another list with same length
>>> map(lambda x: x>=4, a)  # this will return a boolean list 
[False, False, False, True, True, True, True, True, True]


>>> import itertools
>>> itertools.compress(d, map(lambda x: x>4, a)) # magic here !
<itertools.compress object at 0xa1a764c>     # compress will match pair from list a and the boolean list, if item in boolean list is true, then item in list a will be remain ,else will be dropped
#below single line is enough to solve your problem
>>> [ _ for _ in itertools.compress(d, map(lambda x: x>=4,a)) ] # iterate the result.
['d', 'e', 'f', 'g', 'h', 'j']

对itertools.compress的解释,我想这对你的理解会很清楚:

>>> [ _ for _ in itertools.compress([1,2,3,4,5],[False,True,True,False,True]) ]
[2, 3, 5]

【讨论】:

@OliverAmundsen 这将是我的最终解决方案 成功了!谢谢@ShawnZhang。能简单解释一下“使用列表推导”的逻辑吗?谢谢【参考方案4】:
>>> [i for i,v in enumerate(a) if v > 4]
[4, 5, 6, 7, 8]

enumerate 返回数组中每一项的索引和值。因此,如果 v 的值大于 4,则将索引 i 包含在新数组中。

或者您可以只修改您的列表并排除4以上的所有值。

>>> a[:] = [x for x in a if x<=4]
>>> a 
[1, 2, 3, 4]

【讨论】:

【参考方案5】:

使用过滤器内置功能就可以了

>>>a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>filter(lambda x : x < 4, a)
[1, 2, 3]

说明

过滤器(有趣,可迭代)

这个表达式将迭代Iterable中的所有元素并提供给FUN函数作为参数,如果返回为True,那么参数将被附加到一个内部列表中

λx: x > 4

这意味着一个匿名函数,它将接受一个参数并测试它是否大于 4,并返回 True of False 值

您的解决方案

如果你想删除所有大于 4 的元素,那就试试吹

>>> a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> filter(lambda x: x<4 ,a)
[1, 2, 3]

【讨论】:

当你打电话给del a[9]会发生什么? -1。您正在返回列表元素,而不是索引。虽然这适用于给定的列表,但它不是正确的答案。 @Aesthete 这里a的长度是9,a[9]表示list的第10个元素。如果del a[9],python会抛出索引错误 @0xc0de 嗨,您的严谨态度很好。但作为问题的上下文,索引返回将用于删除列表中的元素。我认为我写的内容会有所帮助,并展示关闭票证的 Pythonic 方式。 @ShawnZhang:是的。我认为这个问题需要更正。请编辑您的答案,以反映您认为提问者需要什么和他要求什么之间的差异,以便我取消我的 -1 :)。【参考方案6】:
>>> import numpy as np
>>> a = np.array(range(1,10))
>>> indices = [i for i,v in enumerate(a >= 4) if v]
>>> indices
[3, 4, 5, 6, 7, 8]

>>> mask = a >= 4
>>> mask
array([False, False, False,  True,  True,  True,  True,  True,  True], dtype=boo
l)
>>> a[mask]
array([4, 5, 6, 7, 8, 9])
>>> np.setdiff1d(a,a[mask])
array([1, 2, 3])

【讨论】:

以上是关于查找大于 x 的元素的索引的主要内容,如果未能解决你的问题,请参考以下文章

是否有用于查找向量中元素索引的 R 函数?

c#查找最长连续子数组第一个和最后一个元素索引

二分查找最优实现

《图解算法》--二分查找选择排序递归

Go-二分查找算法

深入理解Mysql索引底层数据结构与算法