Python:包含数组之间条件的列表列表,而不是for循环

时间:2015-06-25 07:09:40

标签: python numpy

我有3个大数组(数百万个元素的顺序)x,v1,v2。阵列x和v1具有相同的大小并且与v2的大小不同。数组v1和v2将具有一些共同的元素。在数组v1和v2之间给出条件的情况下,我想生成一个包含x元素的列表:v1和v2的每个重合都将元素x合并到列表中,最终成员与数组v2中的元素一样多。 到目前为止,我已经完成了这项工作,它完全符合我的要求:

list_foo = []    
for k in range( 0 , N ): # N = len(v2) 
    list_foo.append( x[ v1 == v2[k] ] )

问题:for循环的存在似乎有问题          一个很好的python练习和所涉及的阵列的大尺寸。这段代码在我的机器上花了大约1.5秒(MacOsX 10.8,python 2),有250,000个元素的数组

问题:有更好的方法吗?

第二次尝试:我尝试过列表理解实践:

list_foo = [ [goo] for goo in x if (v1 == v2) ]

我到目前为止所遇到的问题是我不知道如何解决"指数 for循环中比较点v1 == v2[k]的依赖性使其适应列表推导方法。

修改

以下建议涉及列表理解和numpy我做了一个比较的测试。我已经验证了3段代码产生了所需的输出。

import numpy as np
import timeit

# testing for loop
list_foo_for = []
start_time_for = timeit.default_timer()
for k in range( 0 , len(v2) ):
    list_foo_for.append( x[ v1 == v2[k] ] )
elapsed_for = timeit.default_timer() - start_time_for

# testing list comprehension
start_time_comp = timeit.default_timer()
list_foo_comp = [ x[ v1 == v2[k] ] for k in range(0,len(v2))]
elapsed_comp = timeit.default_timer() - start_time_comp

# testing numpy help
start_time_np = timeit.default_timer()
list_foo_np = [ x[k] for k in np.array([v1 == v for v in v2])]
elapsed_np = timeit.default_timer() - start_time_np

Comparison of 3 suggestions...

我可以看到,在过程中纳入numpy在时间执行上要大一个数量级。在数组元素数量少的限制 与for循环相比没有区别。当数组更大时我可以看到时间执行增加了大约10%,所以到目前为止我将使用列表理解建议。

2 个答案:

答案 0 :(得分:0)

您可能正在寻找enumerate

list_foo = [ [goo] for j, goo in enumerate(x) if (v1[j] == v2[j]) ]

当然,您可能需要根据您的需要对其进行修改,上面的代码将生成一个列表(每个包含x中的一个元素),条件为真。

你也可以使用list comprehention(即t[x[ v1 == v2[k] ] for k in range(0,N)])来代替循环。然而,问题是它是否会显着提高速度,你必须进行测试。

答案 1 :(得分:0)

我能从您的问题中理解的是,您希望使用列表理解来完成第一个函数的功能。如果这就是你的意思,那么就在这里。

from numpy import *

x = array([1, 2, 3, 4, 5, 6])
v1 = array([1, 2, 3, 4, 5, 6])
v2 = array([4, 1, 6, 5])

list_foo = [x[j] for j in array([v1 == v for v in v2])]

它为您提供了一个numpy数组列表,与第一个函数相同。