numpy.einsum
-
numpy.einsum(subscripts, *operands, out=None, dtype=None, order='K', casting='safe', optimize=False)[source] -
Вычисляет соглашение об индексе Эйнштейна для операндов.
С помощью соглашения об индексе Эйнштейна многие распространенные операции с многомерными массивами могут быть представлены простым способом. Эта функция предоставляет способ вычисления таких сумм. Лучший способ понять эту функцию — попробовать примеры ниже, которые показывают, как многие общие функции NumPy могут быть реализованы как вызовы к
einsum.Параметры: -
subscripts : str -
Указывает подстроки для суммирования.
-
operands : list of array_like -
Это массивы для операции.
-
out : {ndarray, None}, optional -
Если указано, вычисление выполняется в этом массиве.
-
dtype : {data-type, None}, optional -
Если указано, вычисление выполняется с указанным типом данных. Обратите внимание, что вам может потребоваться также указать более либеральный параметр
castingдля разрешения преобразований. По умолчанию — None. -
order : {‘C’, ‘F’, ‘A’, ‘K’}, optional -
Управляет представлением выходных данных в памяти. ‘C’ означает, что он должен быть C-непрерывным. ‘F’ означает, что он должен быть Fortran-непрерывным, ‘A’ означает, что он должен быть ‘F’, если все входные данные — ‘F’, ‘C’ в противном случае. ‘K’ означает, что он должен быть максимально приближен к представлению входных данных, включая произвольно переставленные оси. По умолчанию — ‘K’.
-
casting : {‘no’, ‘equiv’, ‘safe’, ‘same_kind’, ‘unsafe’}, optional -
Управляет видом приведения типов данных, которое может произойти. Не рекомендуется устанавливать его в значение ‘unsafe’, так как это может неблагоприятно повлиять на накопление.
- ‘no’ означает, что типы данных вообще не должны преобразовываться.
- ‘equiv’ означает, что допускаются только изменения порядка байтов.
- ‘safe’ означает, что допускаются только преобразования, которые могут сохранить значения.
- ‘same_kind’ означает, что допускаются только безопасные преобразования или преобразования в пределах типа, например, float64 в float32.
- ‘unsafe’ означает, что любые преобразования данных могут быть выполнены.
По умолчанию — ‘safe’.
-
optimize : {False, True, ‘greedy’, ‘optimal’}, optional -
Управляет тем, будет ли происходить промежуточная оптимизация. Оптимизация не будет происходить, если значение False, а True по умолчанию будет использовать алгоритм ‘greedy’. Также принимает явный список сокращений из функции
np.einsum_path. См.np.einsum_path, чтобы узнать больше.
Возвращает: -
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)не влияет на 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-массива.Введено в версии 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.]]) -
© 2005–2019 NumPy Developers
Licensed under the 3-clause BSD License.
https://docs.scipy.org/doc/numpy-1.15.4/reference/generated/numpy.einsum.html