numpy.einsum
-
numpy.einsum(subscripts, *operands, out=None, dtype=None, order='K', casting='safe', optimize=False)[source] -
Вычисляет соглашение об индексе Эйнштейна для операндов.
Используя соглашение об индексе Эйнштейна, многие распространённые операции с многомерными массивами могут быть представлены в простом виде. Эта функция предоставляет способ вычисления таких сумм. Лучший способ понять эту функцию — попробовать примеры ниже, которые показывают, как многие распространённые функции NumPy могут быть реализованы как вызовы к
einsum.Параметры: subscripts : str
Указывает индексы для суммирования.
operands : список array_like
Это массивы для операции.
out : {ndarray, None}, необязательно
Если указано, вычисление выполняется в этом массиве.
dtype : {тип данных, None}, необязательно
Если указано, принудительно используется указанный тип данных. Обратите внимание, что вам может потребоваться также предоставить более свободный параметр
castingдля разрешения преобразований. По умолчанию None.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’ означает, что любые преобразования данных могут быть выполнены.
По умолчанию — ‘safe’.
optimize : {False, True, ‘greedy’, ‘optimal’}, необязательно
Управляет тем, должна ли происходить промежуточная оптимизация. Оптимизация не будет происходить, если значение False, а True по умолчанию будет использовать алгоритм ‘greedy’. Также принимает явный список сокращений из функции
np.einsum_path. См.np.einsum_pathдля получения дополнительной информации. По умолчанию False.Возвращает: output : ndarray
Вычисление на основе соглашения об индексе Эйнштейна.
См. также
einsum_path,dot,inner,outer,tensordot,linalg.multi_dotПримечания
Новая функция в версии 1.6.0.
Строка subscripts — это список индексов, разделённых запятыми, где каждый индекс относится к размерности соответствующего операнда. Повторяющиеся индексы в одном операнде принимают диагональ. Например,
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).Если имеется только один операнд, оси не суммируются и не задан параметр 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)вернёт изменяемое представление диагонали 2D-массива.Новая функция в версии 1.12.0.
Добавлен аргумент
optimize, который оптимизирует порядок сокращения выражения einsum. Для сокращений с тремя или более операндами это может значительно повысить вычислительную эффективность за счёт большей потребности в памяти во время вычислений.См.
np.einsum_pathдля получения дополнительной информации.Примеры
>>> 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(',ij', 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–2017 NumPy Developers
Licensed under the NumPy License.
https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.einsum.html