numpy.einsum
-
numpy.einsum(subscripts, *operands, out=None, dtype=None, order='K', casting='safe', optimize=False)[source] -
Вычисляет соглашение об индексации Эйнштейна для операндов.
Используя соглашение об индексации Эйнштейна, многие общие многомерные операции с массивами могут быть представлены простым способом. Эта функция предоставляет способ вычисления таких сумм. Лучший способ понять эту функцию — попробовать примеры ниже, которые показывают, как многие общие функции NumPy могут быть реализованы как вызовы к
einsum.Параметры: подстроки : str
Указывает индексы для суммирования.
операнды : список 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.Возвращает: выходные данные : 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.]])
© 2008–2017 NumPy Developers
Licensed under the NumPy License.
https://docs.scipy.org/doc/numpy-1.12.0/reference/generated/numpy.einsum.html