为什么要花费这么长的Numpy阵列过滤代码?

时间:2019-03-27 07:40:38

标签: python numpy

我有这段代码可以从零行中过滤大型numpy数组(6000000行)。

nonZero_training_data=[]
for i in get_training_data:
    if (np.equal(i[0],[[0,0,0,0],[0,0,0,0]]).all()):
        continue
    nonZero_training_data=nonZero_training_data+[i]

数组中的每一行都是这样的:     [(array([[x1,x2,x3,x4],              [x1,x2,x3,x4]]),y),]

但是执行时间很长,可能需要一分钟或更长时间。

这是get_training_data中的前5行:

array([[array([[0.2, 0., 0., 0.],
       [0.9, 0., 0., 3.]]),
        1],
       [array([[0., 4., 1., 0.],
       [0., 0., 1., 0.]]), 1],
       [array([[2., 0., 7., 0.],
       [0., 0., 1., 8.]]),
        0],
       [array([[0., 5., 0., 2.],
       [0., 8., 0., 1.]]),
        0],
       [array([[0., 1., 0., 1.],
       [0., 5., 0., 0.]]),
        1]], dtype=object)

有没有更有效的方法?

对不起,我的英语,我将不胜感激。

2 个答案:

答案 0 :(得分:1)

我不是numpy的专家,但显然您的目标只是通过过滤某些元素来构建列表。您可以使用列表理解来实现此目的,列表理解既快又短:

nonZero_training_data = [i for i in get_training_data if not (np.equal(i[0],[[0,0,0,0],[0,0,0,0]]).all())]

无论如何,您的代码很慢并不奇怪:这样做时,每次尝试添加元素时都会构建并复制一个新列表:

nonZero_training_data = nonZero_training_data + [i]

产生二次时间复杂度。您绝对应该通过以下方式来获得改进:

nonZero_training_data.append(i)

将新元素添加到位,而不是构建新列表,然后将其复制到变量中。

答案 1 :(得分:1)

这是仅使用numpy的解决方案,应该比列表理解要快。

vfunc = np.vectorize(lambda x: not isinstance(x,int) and np.all(x[0] == [[0,0,0,0],[0,0,0,0]]))
mask = vfunc(get_training_data)[:,0]

get_training_data[~mask]

没有向量化:

mask = ~np.apply_along_axis( lambda x: np.all(x[0] == [[0,0,0,0],[0,0,0,0]]), arr = get_training_data,axis= 1)
get_training_data[mask]