Взятие значений из 2D массива векторизованного - PullRequest
1 голос
/ 10 марта 2019

У меня возникли проблемы со следующим.У меня есть массив M x 2N (solution).Я хочу взять значения и поместить их в массивы NM x 2, каждый из которых хранится в отдельном объекте в списке masses.Код не может полагаться на все циклы, потому что в противном случае программа работает очень медленно.Вот моя попытка:

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

Проблема в том, что он просто берет весь массив решений и помещает его в каждый массив l.Любые идеи, почему это может происходить?

В качестве примера, скажем, у меня есть 3 объекта в массиве masses.Вход 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 Ответ

1 голос
/ 10 марта 2019

Вы можете сделать это с пониманием списка.Это быстрее, чем обычный цикл.
Я не знаю, какие объекты хранятся внутри 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:

[
 [[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, это можно сделать так:

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:

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

Как я уже говорил в комментариях, если вы используете понимание спискаупомянуто, прежде чем это работает, но каждая запись masses будет списком одномерного массива.Теперь каждая запись masses является двумерным массивом.
Я не уверен в эффективности, но попробую: индексирование с нулями довольно быстро.
Однако, если вы имеете дело с тоннамиданных, в какой-то момент вам просто нужно мириться с этим.Оптимизация ограничена.

В настройках ООП у вас, скорее всего, есть способ заполнить этот список атрибутов 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, потому что вам нужно перебрать список уже существующих объектов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...