1. 程式人生 > >Python NumPy 中@ at 符號的意思

Python NumPy 中@ at 符號的意思

 除了python標準的@的功能(decorator ),一直不知道幹什麼的,後來查了一下,可以理解成矩陣乘法,見下面的官方文件

PEP 465 - A dedicated infix operator for matrix multiplication

PEP 465 adds the @ infix operator for matrix multiplication. Currently, no builtin Python types implement the new operator, however, it can be implemented by defining __matmul__()

__rmatmul__(), and __imatmul__() for regular, reflected, and in-place matrix multiplication. The semantics of these methods is similar to that of methods defining other infix arithmetic operators.

Matrix multiplication is a notably common operation in many fields of mathematics, science, engineering, and the addition of @

 allows writing cleaner code:

S = (H @ beta - r).T @ inv(H @ V @ H.T) @ (H @ beta - r)

instead of:

S = dot((dot(H, beta) - r).T,
        dot(inv(dot(dot(H, V), H.T)), dot(H, beta) - r))

NumPy 1.10 has support for the new operator:

>>>

>>> import numpy

>>> x = numpy.ones(3)
>>> x
array([ 1., 1., 1.])

>>> m = numpy.eye(3)
>>> m
array([[ 1., 0., 0.],
       [ 0., 1., 0.],
       [ 0., 0., 1.]])

>>> x @ m
array([ 1., 1., 1.])

See also

PEP 465 – A dedicated infix operator for matrix multiplication

PEP written by Nathaniel J. Smith; implemented by Benjamin Peterson.

 另一個參考:

2017 will forever be etched in our memories as the year Python overtook R to become the leading language for Data Science. There are many factors that play into this: Python's simple syntax, the fantastic PyData ecosystem, and of course buy-in from Python's BDFL.

PEP 465 introduced the @ infix operator that is designated to be used for matrix multiplication. The acceptance and implementation of this proposal in Python 3.5 was a signal to the scientific community that Python is taking its role as a numerical computation language very seriously.

I was a Computational Mathematics major in college so matrices are very near and dear to my heart. Shoutout to Professor Jeff Orchard for having us implement matrix algorithms in C++. His Numerical Linear Algebra course was the best class I've ever taken.

In this post, we will explore the @ operator.

In [1]:

import numpy as np

In [2]:

A = np.matrix('3 1; 8 2')
A

Out[2]:

matrix([[3, 1],
        [8, 2]])

In [3]:

B = np.matrix('6 1; 7 9')
B

Out[3]:

matrix([[6, 1],
        [7, 9]])

In [4]:

A @ B

Out[4]:

matrix([[25, 12],
        [62, 26]])

Let's confirm this works

In [5]:

# element at the top left. i.e. (1, 1) aka (0, 0) in python
A[0, 0] * B[0, 0] + A[0, 1] * B[1, 0]

Out[5]:

25

In [6]:

# element at the top right. i.e. (1, 2) aka (0, 1) in python
A[0, 0] * B[0, 1] + A[0, 1] * B[1, 1]

Out[6]:

12

In [7]:

# element at the bottom left. i.e. (2, 1) aka (1, 0) in python
A[1, 0] * B[0, 0] + A[1, 1] * B[1, 0]

Out[7]:

62

In [8]:

# element at the top right. i.e. (2, 2) aka (1, 1) in python
A[1, 0] * B[0, 1] + A[1, 1] * B[1, 1]

Out[8]:

26

In [9]:

# let's put it in matrix form
result = np.matrix([[A[0, 0] * B[0, 0] + A[0, 1] * B[1, 0], A[0, 0] * B[0, 1] + A[0, 1] * B[1, 1]],
                    [A[1, 0] * B[0, 0] + A[1, 1] * B[1, 0], A[1, 0] * B[0, 1] + A[1, 1] * B[1, 1]]])
result

Out[9]:

matrix([[25, 12],
        [62, 26]])

In [10]:

A @ B == result

Out[10]:

matrix([[ True,  True],
        [ True,  True]], dtype=bool)

Looks good!

The Python Data Model specifies that the @ operator invokes __matmul__ and __rmatmul__.

We can overload @ by defining custom behavior for each of the special methods above, but this would result in our API not being Pythonic.