【问题标题】:Return elements from 2D numpy array that satisfy certain conditions从满足特定条件的二维 numpy 数组返回元素
【发布时间】:2018-03-30 07:37:01
【问题描述】:

我有一个(巨大的)二维数组。例如:

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

我需要从中提取满足一定条件的元素

a[:,0]>1 and a[:,1]>2

这样我得到一个数组,其中只有同时满足两个条件的元素

[[2,3],[4,5]]

(我需要在循环中进一步使用它,这可能与问题相关,也可能不相关)

我尝试了以下方法:

np.transpose([np.extract(a[:,0]>1,a[:,0]),np.extract(a[:,1]>2,a[:,1])])

仅当提取的两个数组长度相同时,上述方法才有效。即使它有效,它有时也会返回未配对的对(我明白为什么)

我知道如何在列表中做到这一点

list(filter(lambda b: b[0]>1 and b[1]>2,a))

但是,我想提高效率。所以我正在转向 numpy (因为我读过它通常更有效?) 有什么方法可以在 numpy 中比列表快得多吗? (我会使用包含 100 个元素的数组执行该代码 1000 次。)

更新:遵循 Maarten_vd_Sande 的回答:

以下代码用于检查所用时间:

import numpy as np
import time

b=np.random.rand(10000000,2)
a=b.tolist()
strt=time.time()
c=b[np.logical_and(b[:,0]>0.5,b[:,1]>0.5)]
for (i,j) in c:
    continue
print("Numpy= ",time.time()-strt)
strt=time.time()
for (i,j) in list(filter(lambda m: m[0]>0.5 and m[1]>0.5,a)):
    continue
print("List= ",time.time()-strt)

输出:

Numpy=  2.973170042037964
List=  1.91910982131958

【问题讨论】:

  • 在 lambda 函数中,您检查 >2 会导致一个空列表。将其更改为>0.5,numpy 方法的速度是原来的两倍(如果删除空循环,速度会提高 10 倍以上)。
  • 将其更改为 >0.5。但 Numpy 仍然较慢。您是否进行了任何其他更改?
  • 这是使 numpy 变慢的循环部分,而不是实际的过滤器(尝试将循环注释掉)。也许你可以向量化循环中发生的事情。空循环的 2 秒是瓶颈,还是其中的计算?
  • 尝试不使用循环。正如您之前提到的,Numpy 确实快了一个数量级。但是,循环是必要的,因为在循环内部,无论哪个元素进入,我基本上都需要找到点 (i,j) 和其他点 (x,y) 之间的距离。如果我在循环之前使用 to.list() 将 c 从 numpy 数组转换为列表,那么 numpy 循环似乎比列表循环(1.963 与 2.0201)略好。
  • 不知道之前发生了什么。它确实显示了不同的答案,而我没有触摸阵列。但现在它显示相同。会尝试找出它在哪里,否则我搞砸了。不管怎样,谢谢大家的帮助!

标签: python numpy


【解决方案1】:

你需要在numpy中使用(logical) and

result = a[np.logical_and(a[:,0] > 1,  a[:,1] > 2)]

这对你有用吗?

编辑: 在这种情况下,我们甚至可以充分利用广播:

result = np.greater(a, [1, 2])

【讨论】:

  • logical_and 就像一个魅力!谢谢。但是,它并不像列表方法那么快。不确定是我写的还是 numpy 方法本身效率不高。我应该在这里发布用于检查时间的代码还是提出另一个问题?
  • 这很令人惊讶,我猜你可以在这里发布。我去看看。
  • 无法正确获取 cmets 中的格式,因此我编辑了问题。
猜你喜欢
  • 2018-05-18
  • 1970-01-01
  • 1970-01-01
  • 2012-01-14
  • 1970-01-01
  • 1970-01-01
  • 2021-12-14
  • 1970-01-01
  • 2021-02-15
相关资源
最近更新 更多