numpy.einsum
-
numpy.einsum(subscripts, *operands, out=None, dtype=None, order='K', casting='safe') -
Вычисляет соглашение об Эйнштейновской сумме по операндам.
Используя соглашение об Эйнштейновской сумме, многие общие операции с многомерными массивами можно представить простым способом. Эта функция предоставляет способ вычисления таких сумм. Лучший способ понять эту функцию — попробовать примеры ниже, которые показывают, как многие общие функции NumPy могут быть реализованы как вызовы к
einsum.Параметры: подстроки : str
Указывает подстроки для суммирования.
операнды : список 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’ означает, что могут быть выполнены любые преобразования данных.
Возвращает: выход : 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)не влияет на 2D-массив, в то время как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).Когда существует только один операнд, оси не суммируются, и параметр вывода не указан, вместо нового массива возвращается представление операнда. Таким образом, взятие диагонали как
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)вернёт изменяемое представление диагонали 2D-массива.Примеры
>>> 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.10.1/reference/generated/numpy.einsum.html