Эффективный способ заменить повторение np.vstack в Python? - PullRequest
3 голосов
/ 28 мая 2019

Я пытаюсь реализовать это сообщение в Python.

import numpy as np
x = np.array([0,0,0])
for r in range(3):
    x = np.vstack((x, np.array([-r, r, -r])))

x получает это значение

array([[ 0,  0,  0],
       [ 0,  0,  0],
       [-1,  1, -1],
       [-2,  2, -2]])

Я обеспокоен эффективностью выполнения во времяповторяющийся np.vstack.Есть ли более эффективный способ сделать это?

Ответы [ 3 ]

4 голосов
/ 28 мая 2019

Создайте список массивов или списков и примените к нему один раз np.array (или vstack):

In [598]: np.array([[-r,r,-r] for r in [0,0,1,2]])                                                    
Out[598]: 
array([[ 0,  0,  0],
       [ 0,  0,  0],
       [-1,  1, -1],
       [-2,  2, -2]])

Но если шаблон столбцов согласован, вещание двух массивов друг против друга будет быстрее

In [599]: np.array([-1,1,-1])*np.array([0,0,1,2])[:,None]                                             
Out[599]: 
array([[ 0,  0,  0],
       [ 0,  0,  0],
       [-1,  1, -1],
       [-2,  2, -2]])
1 голос
/ 28 мая 2019

Было бы полезно использовать numpy.tile?

 N = 3
 A = np.array([[0, *range(0, -N, -1)]]).T
 B = np.tile(A, (1, N))
 B[:,1] = -B[:,1]

В первой строке указывается ожидаемое количество строк после первой строки нулей.Второй создает массив NumPy, создавая начальное значение 0, за которым следует линейная последовательность от 0, -1, -2 до -N + 1.Обратите внимание на использование оператора splat, который распаковывает объект range и создает элементы в отдельном списке.Они объединяются с первым значением 0, и мы создаем двумерный массив NumPy, который является вектором столбца.Третья строка накладывает этот вектор N раз по горизонтали, чтобы получить желаемый результат.Наконец, четвертая строка отменяет второй столбец, чтобы получить желаемый результат

Пример выполнения

In [175]: N = 3

In [176]: A = np.array([[0, *range(0, -N, -1)]]).T

In [177]: B = np.tile(A, (1, N))

In [178]: B[:,1] = -B[:,1]

In [178]: B
Out[178]:
array([[ 0,  0,  0],
       [ 0,  0,  0],
       [-1,  1, -1],
       [-2,  2, -2]])
1 голос
/ 28 мая 2019

Вы можете использовать np.block следующим образом:

  • Сначала создайте блок, который вы сейчас делаете внутри цикла for
  • Наконец, вертикально сложите строку нулей, используя np.vstack, чтобы получить окончательный желаемый ответ

import numpy as np

size = 3
sign = np.ones(3)*((-1)**np.arange(1, size+1)) # General sign array of repeating -1, 1

A = np.ones((size, size), int)
B = np.arange(0, size) * A
B = sign * np.block([B.T])         

# array([[ 0,  0,  0],
#        [ -1, 1, -1],
#        [ -2, 2, -2]])

answer = np.vstack([B[0], B])

# array([[ 0,  0,  0],
#        [ 0,  0,  0],
#        [ -1, 1, -1],
#        [ -2, 2, -2]])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...