numpy.einsum
-
numpy.einsum(subscripts, *operands, out=None, dtype=None, order='K', casting='safe') -
Вычисляет соглашение об эйнштейновской сумме для операндов.
Используя соглашение об эйнштейновской сумме, многие распространённые операции с многомерными массивами можно представить в простой форме. Эта функция предоставляет способ вычисления таких сумм. Лучший способ понять эту функцию — попробовать примеры ниже, которые показывают, как многие распространённые функции NumPy можно реализовать как вызовы к
einsum.Параметры: subscripts : str
Указывает индексы для суммирования.
operands : список array_like
Это массивы для операции.
out : ndarray, необязательно
Если задано, вычисление выполняется в этом массиве.
dtype : тип данных, необязательно
Если задано, принудительно используется указанный тип данных. Обратите внимание, что может потребоваться также предоставить более универсальный
castingпараметр, чтобы разрешить преобразования.order : {‘C’, ‘F’, ‘A’, ‘K’}, необязательно
Управляет структурой памяти выходных данных. ‘C’ означает, что он должен быть C-непрерывным. ‘F’ означает, что он должен быть Fortran-непрерывным, ‘A’ означает, что он должен быть ‘F’, если все входные данные ‘F’, иначе ‘C’. ‘K’ означает, что он должен быть максимально приближен к структуре данных входных данных, включая произвольно переставленные оси. По умолчанию — ‘K’.
casting : {‘no’, ‘equiv’, ‘safe’, ‘same_kind’, ‘unsafe’}, необязательно
Управляет тем, какие преобразования данных могут произойти. Не рекомендуется устанавливать это значение в ‘unsafe’, так как это может негативно повлиять на накопление.
- ‘no’ означает, что типы данных вообще не должны преобразовываться.
- ‘equiv’ означает, что разрешаются только изменения порядка байтов.
- ‘safe’ означает, что разрешаются только преобразования, которые могут сохранить значения.
- ‘same_kind’ означает, что разрешаются только безопасные преобразования или преобразования внутри типа, например, float64 в float32.
- ‘unsafe’ означает, что любые преобразования данных могут быть выполнены.
Возвращает: output : ndarray
Вычисление на основе соглашения об эйнштейновской сумме.
Примечания
Новая в версии 1.6.0.
Строка индексов — это список индексов, разделённых запятыми, где каждый индекс относится к размерности соответствующего операнда. Повторяющиеся индексы в одном операнде принимают диагональ. Например,
np.einsum('ii', a)эквивалентноnp.trace(a).Всякий раз, когда индекс повторяется, он суммируется, поэтому
np.einsum('i,i', a, b)эквивалентноnp.inner(a,b). Если индекс встречается только один раз, он не суммируется, поэтомуnp.einsum('i', a)создаёт видaбез изменений.Порядок индексов в выходных данных по умолчанию алфавитный. Это означает, что
np.einsum('ij', a)не влияет на двумерный массив, аnp.einsum('ji', a)меняет его на транспонированный.Выходные данные можно контролировать, указав индексы выходных данных. Это определяет порядок индексов и позволяет запретить или принудительно запретить суммирование, если необходимо. Вызов
np.einsum('i->', a)аналогичен вызовуnp.sum(a, axis=-1), аnp.einsum('ii->i', a)аналогиченnp.diag(a). Разница в том, чтоeinsumпо умолчанию не допускает вещания.Для включения и управления вещанием используйте эллипсис. Вещание по умолчанию в стиле NumPy выполняется путём добавления эллипса слева от каждого члена, как в
np.einsum('...ii->...i', a). Для взятия следа по первой и последней оси можно выполнитьnp.einsum('i...i', a), или для выполнения матрично-матричного произведения с левыми индексами вместо правых —np.einsum('ij...,jk...->ik...', a, b).Когда существует только один операнд, оси не суммируются, и параметр output не указан, вместо нового массива возвращается вид на операнд. Таким образом, взятие диагонали как
np.einsum('ii->i', a)создаёт вид.Альтернативный способ предоставления индексов и операндов —
einsum(op0, sublist0, op1, sublist1, ..., [sublistout]). Примеры ниже имеют соответствующие вызовыeinsumс методами с двумя параметрами.Новая в версии 1.10.0.
Возвращаемые значения из einsum теперь могут быть изменяемыми, когда входной массив изменяем. Например,
np.einsum('ijk...->kji...', a)теперь будет иметь тот же эффект, что иnp.swapaxes(a, 0, 2), аnp.einsum('ii->i', a)вернёт изменяемый вид диагонали двумерного массива.Примеры
>>> a = np.arange(25).reshape(5,5) >>> b = np.arange(5) >>> c = np.arange(6).reshape(2,3)
>>> np.einsum('ii', a) 60 >>> np.einsum(a, [0,0]) 60 >>> np.trace(a) 60>>> np.einsum('ii->i', a) array([ 0, 6, 12, 18, 24]) >>> np.einsum(a, [0,0], [0]) array([ 0, 6, 12, 18, 24]) >>> np.diag(a) array([ 0, 6, 12, 18, 24])>>> np.einsum('ij,j', a, b) array([ 30, 80, 130, 180, 230]) >>> np.einsum(a, [0,1], b, [1]) array([ 30, 80, 130, 180, 230]) >>> np.dot(a, b) array([ 30, 80, 130, 180, 230]) >>> np.einsum('...j,j', a, b) array([ 30, 80, 130, 180, 230])>>> np.einsum('ji', c) array([[0, 3], [1, 4], [2, 5]]) >>> np.einsum(c, [1,0]) array([[0, 3], [1, 4], [2, 5]]) >>> c.T array([[0, 3], [1, 4], [2, 5]])>>> np.einsum('..., ...', 3, c) array([[ 0, 3, 6], [ 9, 12, 15]]) >>> np.einsum(3, [Ellipsis], c, [Ellipsis]) array([[ 0, 3, 6], [ 9, 12, 15]]) >>> np.multiply(3, c) array([[ 0, 3, 6], [ 9, 12, 15]])>>> np.einsum('i,i', b, b) 30 >>> np.einsum(b, [0], b, [0]) 30 >>> np.inner(b,b) 30>>> np.einsum('i,j', np.arange(2)+1, b) array([[0, 1, 2, 3, 4], [0, 2, 4, 6, 8]]) >>> np.einsum(np.arange(2)+1, [0], b, [1]) array([[0, 1, 2, 3, 4], [0, 2, 4, 6, 8]]) >>> np.outer(np.arange(2)+1, b) array([[0, 1, 2, 3, 4], [0, 2, 4, 6, 8]])>>> np.einsum('i...->...', a) array([50, 55, 60, 65, 70]) >>> np.einsum(a, [0,Ellipsis], [Ellipsis]) array([50, 55, 60, 65, 70]) >>> np.sum(a, axis=0) array([50, 55, 60, 65, 70])>>> a = np.arange(60.).reshape(3,4,5) >>> b = np.arange(24.).reshape(4,3,2) >>> np.einsum('ijk,jil->kl', a, b) array([[ 4400., 4730.], [ 4532., 4874.], [ 4664., 5018.], [ 4796., 5162.], [ 4928., 5306.]]) >>> np.einsum(a, [0,1,2], b, [1,0,3], [2,3]) array([[ 4400., 4730.], [ 4532., 4874.], [ 4664., 5018.], [ 4796., 5162.], [ 4928., 5306.]]) >>> np.tensordot(a,b, axes=([1,0],[0,1])) array([[ 4400., 4730.], [ 4532., 4874.], [ 4664., 5018.], [ 4796., 5162.], [ 4928., 5306.]])>>> a = np.arange(6).reshape((3,2)) >>> b = np.arange(12).reshape((4,3)) >>> np.einsum('ki,jk->ij', a, b) array([[10, 28, 46, 64], [13, 40, 67, 94]]) >>> np.einsum('ki,...k->i...', a, b) array([[10, 28, 46, 64], [13, 40, 67, 94]]) >>> np.einsum('k...,jk', a, b) array([[10, 28, 46, 64], [13, 40, 67, 94]])>>> # since version 1.10.0 >>> a = np.zeros((3, 3)) >>> np.einsum('ii->i', a)[:] = 1 >>> a array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., 1.]])
© 2008–2016 NumPy Developers
Licensed under the NumPy License.
https://docs.scipy.org/doc/numpy-1.11.0/reference/generated/numpy.einsum.html