Умножить индексы массива на числа - PullRequest
1 голос
/ 10 февраля 2020

есть ли короткая команда numpy для следующей операции в циклах for?

import numpy as np


a= np.array([1.0,2.0,3.0,4.0,5.0,6.0])
b= np.array([10.0,20.0,30.0])
c= np.array([100.0,200.0,300.0,900.0])
y=np.linspace(0,2,50)
m=np.array([0.2,0.1,0.3])

A,C,B,Y = np.meshgrid(a,c,b,y,indexing="ij")

print Y

for i in range(0,len(a)):
  for j in range(0,len(c)):
    for k in range(0,len(b)):
      Y[i][j][k]=Y[i][j][k]*m[k]


print "--------"
print Y

Абстрактно у меня есть $ Y_ {ijkl} $, и я хочу умножить $ Y_ {ij0l} $ на $ m_0 $ и $ Y_ {ij1l} $ с $ m_1 $ и так далее ...

Заранее большое спасибо!

1 Ответ

2 голосов
/ 10 февраля 2020

Чтобы удалить l oop, вам просто нужно einsum здесь.

np.einsum('ijkl,k->ijkl', Y, m)

или только что переданное умножение:

Y * m[:, None]

Однако, если вы не Если вы не хотите создавать сетку в первую очередь, вы можете сначала передать Y, чтобы увеличить эффективность памяти.

np.einsum(
    "ijkl,k->ijkl",
    np.broadcast_to(y, a.shape + c.shape + b.shape + y.shape),
    m,
)

или:

np.broadcast_to(y, a.shape + c.shape + b.shape + y.shape) * m[:, None]

Если вам нужно A, C, B, а также, вы можете продолжить свой текущий подход.


Производительность

In [44]: %%timeit
    ...: np.einsum(
    ...:     "ijkl,k->ijkl",
    ...:     np.broadcast_to(y, (a.shape[0], c.shape[0], b.shape[0], y.shape[0])),
    ...:     m,
    ...: )
    ...:
21.1 µs ± 121 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

In [45]: %%timeit
    ...: A,C,B,Y = np.meshgrid(a,c,b,y,indexing="ij")
    ...: for i in range(0,len(a)):
    ...:   for j in range(0,len(c)):
    ...:     for k in range(0,len(b)):
    ...:       Y[i][j][k]=Y[i][j][k]*m[k]
    ...:
420 µs ± 1.58 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
...