【问题标题】:Find the indices of elements greater than x查找大于 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 作为索引来从另一个列表中删除元素,而不是...

标签: python indexing logical-operators indices


【解决方案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])
        

        【讨论】:

          猜你喜欢
          • 2021-07-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-11-07
          • 2021-06-20
          • 1970-01-01
          相关资源
          最近更新 更多