Как умножить массив пустых кортежей на скалярный массив - PullRequest
3 голосов
/ 04 июля 2011

У меня есть числовой массив A формы (N, 2) и числовой массив S формы (N).

Как мне умножить оба массива?В настоящее время я использую этот код:

tupleS = numpy.zeros( (N , 2) )
tupleS[:,0] = S
tupleS[:,1] = S
product = A * tupleS

Я начинающий Python.Есть ли лучший способ сделать это?

Ответы [ 5 ]

6 голосов
/ 04 июля 2011

Numpy использует основной порядок строк, поэтому вам нужно явно создать столбец.Как в:

>> A = numpy.array(range(10)).reshape(5, 2)
>>> B = numpy.array(range(5))
>>> B
array([0, 1, 2, 3, 4])
>>> A * B
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: shape mismatch: objects cannot be broadcast to a single shape
>>> B = B.reshape(5, 1)
>>> B
array([[0],
       [1],
       [2],
       [3],
       [4]])
>>> A * B
array([[ 0,  0],
       [ 2,  3],
       [ 8, 10],
       [18, 21],
       [32, 36]])
3 голосов
/ 04 июля 2011

По сути то же самое, что и ответ @ senderle, но не требует манипулирования на месте S. Вы можете получить срез массива способом, который добавляет оси с индексом None, и это умножит их: A * S[:,None].

>>> S = np.arange(5)
>>> S
array([0, 1, 2, 3, 4])
>>> A = np.arange(10).reshape((5,2))
>>> A
array([[0, 1],
       [2, 3],
       [4, 5],
       [6, 7],
       [8, 9]])
>>> S[:,None]
array([[0],
       [1],
       [2],
       [3],
       [4]])
>>> A * S[:,None]
array([[ 0,  0],
       [ 2,  3],
       [ 8, 10],
       [18, 21],
       [32, 36]])
1 голос
/ 04 июля 2011

Хотя название вашего вопроса немного неправильное, я думаю, что проблема, с которой вы столкнулись, в основном связана с numpy правилами вещания .Таким образом, следующее не будет работать (как вы уже заметили):

In []: N= 5
In []: A= rand(N, 2)
In []: A.shape
Out[]: (5, 2)

In []: S= rand(N)
In []: S.shape
Out[]: (5,)

In []: A* S
------------------------------------------------------------
Traceback (most recent call last):
  File "<ipython console>", line 1, in <module>
ValueError: operands could not be broadcast together with shapes (5,2) (5) 

Однако, теперь простой способ сделать S совместимым с правилами вещания (поэлементного произведения A* S),расширить его размерность, например:

In []: A* S[:, None]
Out[]: 
array([[ 0.54216549,  0.04964989],
       [ 0.41850647,  0.4197221 ],
       [ 0.03790031,  0.76744563],
       [ 0.29381325,  0.53480765],
       [ 0.0646535 ,  0.07367852]])

Но это действительно ничего, кроме синтаксического сахара для expand_dims , например:

In []: expand_dims(S, 1).shape
Out[]: (5, 1)

В любом случае, я лично предпочитаю этопростой подход без проблем:

In []: S= rand(N, 1)
In []: S.shape
Out[]: (5, 1)

In []: A* S
Out[]: 
array([[ 0.40421854,  0.03701712],
       [ 0.63891595,  0.64077179],
       [ 0.03117081,  0.63117954],
       [ 0.24695035,  0.44950641],
       [ 0.14191946,  0.16173008]])

Таким образом, с python;быть более простым, чем явным, явным.

1 голос
/ 04 июля 2011

Вы пробовали это:

product = A * S
0 голосов
/ 04 июля 2011

Я могу думать о:

product = A * numpy.tile(S, (2,1)).T

Более быстрое решение может быть:

product = [d * S for d in A.T]

, хотя это не дает вам массив данных в качестве вывода, и он транспонирован.Таким образом, чтобы получить аналогичный массив NumPy (обратите внимание, что это медленнее, чем первое решение):

product = numpy.array([d * S for d in A.T]).T

Вероятно, существует дюжина других допустимых решений, в том числе лучшие, чем эти ...

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