简体   繁体   English

从二维数组中取值向量化

[英]Taking values from 2D array vectorized

I am having some trouble with the following.我在以下方面遇到了一些麻烦。 I have a M x 2N array ( solution ).我有一个 M x 2N 阵列( solution )。 I want to take the values and put them into NM x 2 arrays, each stored in a different object in the list masses .我想获取这些值并将它们放入 NM x 2 数组中,每个数组都存储在列表masses中的不同对象中。 The code cannot rely on all loops because the program is very slow otherwise.代码不能依赖所有循环,否则程序会很慢。 Here is my attempt:这是我的尝试:

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

The problem is, this just takes the entire solution array and puts it in each l array.问题是,这只是获取整个解决方案数组并将其放入每个l数组中。 Any ideas why this might be happening?任何想法为什么会发生这种情况?

As an example, say I have 3 objects in the array masses .例如,假设我在数组masses有 3 个对象。 The solution input is solution输入是

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

The expected values of l in each of the objects in masses is:每个masses物体中l的期望值为:

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]]

Instead, each l array is just set as the the solution array.相反,每个l数组只是设置为solution数组。

You could do this with a list comprehension.你可以用列表理解来做到这一点。 It's faster than a normal loop.它比普通循环更快。
I do not know what objects are stored inside masses , so for the sake of this example let me use masses as a simple list.我不知道是什么对象都存储在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 is: masses是:

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

Which should be what you want.这应该是你想要的。

Guessing how to use it with your masses list, it shoud be:猜测如何将它与您的masses名单一起使用,它应该是:

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

Just be sure that you have enough objects in your self.masses list, or you will get an IndexError .只要确保你的self.masses列表中有足够的对象,否则你会得到一个IndexError

EDIT after comments评论后编辑

If solution is a Mx2N numpy array, it can be done like this:如果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 is: masses是:

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

As I said in the comments, if you use the list comprehension mentioned before it works, but each masses entry will be a list of 1D numpy array.正如我在评论中所说,如果您使用之前提到的列表推导式,但每个masses条目都将是一维 numpy 数组的列表。 Now each masses entry is a 2D numpy array.现在每个masses条目都是一个 2D numpy 数组。
I am not sure about efficiency, but give it a try: numpy indexing is quite fast.我不确定效率,但试一试: numpy 索引非常快。
However if you are dealing with tons of data, at some point you just need to bear with it.但是,如果您正在处理大量数据,在某些时候您只需要忍受它。 There is a limit on optimization.优化是有限制的。

In your OOP setting, you likely have a method to populate that self.masses attribute list.在您的 OOP 设置中,您可能有一种方法来填充该self.masses属性列表。 It should be something like:它应该是这样的:

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

I am afraid there is not easy way to avoid the for loop in this case, because you need to loop over a list of already existing objects.在这种情况下,恐怕没有简单的方法可以避免for循环,因为您需要遍历已存在对象的列表。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM