从2D数组矢量化获取值

时间:2019-03-10 14:57:00

标签: python vectorization

我在以下方面遇到了麻烦。我有一个M x 2N数组(solution)。我想将这些值放入N M x 2数组中,每个数组存储在列表masses中的不同对象中。代码不能依赖所有循环,否则程序会非常慢。这是我的尝试:

        for i in range(len(masses)):
            self.masses[i].l = solution[:len(solution)][2*i: 2*(i + 1)]

问题是,这只需要使用整个解决方案数组并将其放入每个l数组中。为什么会发生这种情况的任何想法?

举个例子,假设我在数组masses中有3个对象。 solution输入为

[[0,0,0,0,0,0]
 [1,2,3,4,5,6]
 [2,4,6,8,10,12]]

l中每个对象中masses的期望值为:

self.masses[0].l = [[0,0]
                    [1,2]
                    [2,4]]


self.masses[1].l = [[0,0]
                    [3,4]
                    [6,8]]

self.masses[2].l = [[0,0]
                    [5,6]
                    [10,12]]

相反,每个l数组都只是设置为solution数组。

1 个答案:

答案 0 :(得分:1)

您可以通过列表理解来做到这一点。它比普通循环要快。
我不知道masses中存储了什么对象,因此,出于本示例的考虑,让我将masses用作简单列表。

solution = [[0,0,0,0,0,0], [1,2,3,4,5,6], [2,4,6,8,10,12]]

masses = [None] * 3 #I get that its length should be half of the length of the inner lists in solution.
for i in range(len(masses)):
     masses[i] = [j[2*i:2*(i+1)] for j in solution]

print(masses)

masses是:

[
 [[0, 0], [1, 2], [2, 4]], 
 [[0, 0], [3, 4], [6, 8]], 
 [[0, 0], [5, 6], [10, 12]]
]

应该是您想要的。

猜测如何在您的masses列表中使用它,应该是:

for i in range(len(masses)):
    self.masses[i].l = [j[2*i:2*(i+1)] for j in solution]

请确保您的self.masses列表中有足够的对象,否则您将获得IndexError

评论后编辑

如果solution是一个Mx2N numpy数组,可以这样进行:

import numpy as np
solution = np.array([[0,0,0,0,0,0], [1,2,3,4,5,6], [2,4,6,8,10,12]])
masses = [solution[...,2*i:2*(i+1)] for i in range(int(solution.shape[1]/2))]

masses是:

[
 array([[0, 0], [1, 2], [2, 4]]), 
 array([[0, 0], [3, 4], [6, 8]]), 
 array([[0, 0], [5, 6], [10, 12]])
]

正如我在评论中所说,如果您使用之前提到的列表理解,则每个masses条目都会是一维numpy数组的列表。现在,每个masses条目都是一个二维numpy数组。
我不确定效率,但可以尝试一下:numpy indexing相当快。
但是,如果要处理大量数据,则有时只需要忍受它即可。优化是有限制的。

在OOP设置中,您可能有一种填充该self.masses属性列表的方法。应该是这样的:

def setmasses(self, solution):
    for i in range(int(solution.shape[1]/2)):
        self.masses[i].l = solution[...,2*i:2*(i+1)]

在这种情况下,恐怕没有简单的方法来避免for循环,因为您需要循环遍历一系列已存​​在的对象。