【发布时间】: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)略好。
-
不知道之前发生了什么。它确实显示了不同的答案,而我没有触摸阵列。但现在它显示相同。会尝试找出它在哪里,否则我搞砸了。不管怎样,谢谢大家的帮助!