numpy里*與dot與multiply


一、*  , dot()   multiply()

1, 對於array來說,(* 和 dot()運算不同, * 和 multiply()運算相同)

*和multiply() 是每個元素對應相乘

dot() 是矩陣乘法

2, 對於matrix來說,(* 和 multiply()運算不同,* 和 dot()運算相同)

* 和dot() 是矩陣乘法

multiply()  是每個元素對應相乘

 

3, 混合的時候(與矩陣同)

multiply 為對應乘

dot為矩陣乘法(矩陣在前數組在后時,均為一維時數組可適應,即能做矩陣乘法)

*為 矩陣乘法(但無上述適應性)

 

總結:dot為矩陣乘法multiply是對應乘* 看元素,元素為矩陣(包括含矩陣)時為矩陣乘法,元素為數組時為對應乘法

 

Python 3.6.4 (default, Jan 7 2018, 03:52:16)
[GCC 4.2.1 Compatible Android Clang 5.0.300080 ] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy as np
>>> a1=np.array([1,2,3])
>>> a1*a1
array([1, 4, 9])
>>> np.dot(a1,a1)
14
>>> np.multiply(a1,a1)
array([1, 4, 9])
>>> m1 = np.mat(a1)
>>> m1
matrix([[1, 2, 3]])
>>> m1*m1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/data/data/com.termux/files/usr/lib/python3.6/site-packages/numpy-1.13.3-py3.6-linux-aarch64.egg/numpy/matrixlib/defmatrix.py", line 309, in __mul__
return N.dot(self, asmatrix(other))
ValueError: shapes (1,3) and (1,3) not aligned: 3 (dim 1) != 1 (dim 0)
>>> np.dot(m1,m1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: shapes (1,3) and (1,3) not aligned: 3 (dim 1) != 1 (dim 0)
>>> np.multiply(m1,m1)
matrix([[1, 4, 9]])
>>> np.multiply(a1,m1)
matrix([[1, 4, 9]])
>>> np.multiply(m1,a1)
matrix([[1, 4, 9]])
>>> np.dot(a1,m1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: shapes (3,) and (1,3) not aligned: 3 (dim 0) != 1 (dim 0)
>>> np.dot(m1,a1)
matrix([[14]])
>>> a1*m1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/data/data/com.termux/files/usr/lib/python3.6/site-packages/numpy-1.13.3-py3.6-linux-aarch64.egg/numpy/matrixlib/defmatrix.py", line 315, in __rmul__
return N.dot(other, self)
ValueError: shapes (3,) and (1,3) not aligned: 3 (dim 0) != 1 (dim 0)
>>> m1*a1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/data/data/com.termux/files/usr/lib/python3.6/site-packages/numpy-1.13.3-py3.6-linux-aarch64.egg/numpy/matrixlib/defmatrix.py", line 309, in __mul__
return N.dot(self, asmatrix(other))
ValueError: shapes (1,3) and (1,3) not aligned: 3 (dim 1) != 1 (dim 0)
>>> a1,m1
(array([1, 2, 3]), matrix([[1, 2, 3]]))
>>>

 -------------------------------------------------------------------

當array是二維時,我們可以把它看做是矩陣(但是乘法的法則還是按照array來算)

In [45]: a_x
Out[45]:
array([[1, 2, 3],
       [2, 4, 0],
       [1, 2, 1]])

In [46]: a_y
Out[46]: array([[-1,  1, -1]])

 

先看dot

# 這時用dot做矩陣乘法要注意:滿足左邊的列數等於右邊的行數

In [47]: np.dot(a_x,a_y)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-47-3b884e90b0ef> in <module>()
----> 1 np.dot(a_x,a_y)

ValueError: shapes (3,3) and (1,3) not aligned: 3 (dim 1) != 1 (dim 0)

In [48]: np.dot(a_y,a_x)
Out[48]: array([[ 0,  0, -4]])

# 當左邊的變為一維的數組時,結果還是一個二維的數組(矩陣形式)

In [49]: a_y_ = a_y.flatten()

In [50]: a_y_
Out[50]: array([-1,  1, -1])

然后還有一點很重要 np.dot(a_y_,a_y_) 可以將兩個一維的數組(這時沒有行列向量之說,從轉置后還為本身也可以看出)直接做內積
In [109]: np.dot(a_y_,a_y_)
Out[109]: 3


In [51]: np.dot(a_y,a_x)
Out[51]: array([[ 0,  0, -4]])

再看multiply(與*的效果一致):

In [52]: a_y
Out[52]: array([[-1,  1, -1]])

In [53]: a_y_
Out[53]: array([-1,  1, -1])

In [54]: np.multiply(a_y,a_y_)
Out[54]: array([[1, 1, 1]])

In [55]: np.multiply(a_y_,a_y)
Out[55]: array([[1, 1, 1]])

得到結論:都是以高維的那個元素決定結果的維度。(重要)

 

In [56]: np.multiply(a_y_,a_y_.T)   # 在a_y_是一維的行向量,a_y_ = a_y_.T,所以結果一樣
Out[56]: array([1, 1, 1])

In [57]: np.multiply(a_y_,a_y.T)    # a_y 是二維的行向量,轉置一下就變成二維的列向量
Out[57]:
array([[ 1, -1,  1],
       [-1,  1, -1],
       [ 1, -1,  1]])
In [58]: np.multiply(a_y,a_y.T)     # 與上述效果相同
Out[58]:
array([[ 1, -1,  1],
       [-1,  1, -1],
       [ 1, -1,  1]])

上面兩個就是下面這倆對應元素相乘!

In [59]: a_y
Out[59]: array([[-1,  1, -1]])

In [60]: a_y.T
Out[60]:
array([[-1],
       [ 1],
       [-1]])

與下面這種張量積效果相同

In [61]: np.outer(a_y,a_y)
Out[61]:
array([[ 1, -1,  1],
       [-1,  1, -1],
       [ 1, -1,  1]])

In [62]: np.outer(a_y,a_y.T)     # 這時用不用轉置的效果都一樣
Out[62]:
array([[ 1, -1,  1],
       [-1,  1, -1],
       [ 1, -1,  1]])

In [63]: np.outer(a_y_,a_y_)    # 兩個一維的行向量外積的效果也一樣
Out[63]:
array([[ 1, -1,  1],
       [-1,  1, -1],
       [ 1, -1,  1]])

 

 

 

 

 

 

 

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

                                                                                    下面看一下 .T 和 .transpose()

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

在小於等於二維的情況下,兩者效果是相同的!

In [64]: x
Out[64]:
matrix([[1, 2, 3],
        [2, 4, 0],
        [1, 2, 1]])

In [65]: a_x
Out[65]:
array([[1, 2, 3],
       [2, 4, 0],
       [1, 2, 1]])

In [68]: (x.T == x.transpose()).all()     # 為矩陣時相同
Out[68]: True

In [70]: (a_x.T == a_x.transpose()).all()    # 為數組時相同
Out[70]: True

 

In [71]: (a_y.T == a_y.transpose()).all()   # a_y為一維數組(行向量)相同
Out[71]: True

In [72]: (a_y_.T == a_y_.transpose()).all() # a_y_為二維數組(行向量)也相同
Out[72]: True

 

下面才是兩種區別的重點:

當維數大於等於三時(此時只有數組了),

T 其實就是把順序全部顛倒過來,

而transpose(), 里面可以指定順序,輸入為一個元組(x0,x1,x2...x(n-1) )為(0,1,2,...,n-1)的一個排列,其中n為數組維數,

效果與np.transpose(arr, axes=(x0,x1,x2...x(n-1)) ) 相同,

    def transpose(self, *axes): # real signature unknown; restored from __doc__
        """
        a.transpose(*axes)
        
            Returns a view of the array with axes transposed.
        
            For a 1-D array, this has no effect. (To change between column and
            row vectors, first cast the 1-D array into a matrix object.)
            For a 2-D array, this is the usual matrix transpose.
            For an n-D array, if axes are given, their order indicates how the
            axes are permuted (see Examples). If axes are not provided and
            ``a.shape = (i[0], i[1], ... i[n-2], i[n-1])``, then
            ``a.transpose().shape = (i[n-1], i[n-2], ... i[1], i[0])``.
        
            Parameters
            ----------
            axes : None, tuple of ints, or `n` ints
        
             * None or no argument: reverses the order of the axes.
        
             * tuple of ints: `i` in the `j`-th place in the tuple means `a`'s
               `i`-th axis becomes `a.transpose()`'s `j`-th axis.
        
             * `n` ints: same as an n-tuple of the same ints (this form is
               intended simply as a "convenience" alternative to the tuple form)
        
            Returns
            -------
            out : ndarray
                View of `a`, with axes suitably permuted.
        
            See Also
            --------
            ndarray.T : Array property returning the array transposed.
        
            Examples
            --------
            >>> a = np.array([[1, 2], [3, 4]])
            >>> a
            array([[1, 2],
                   [3, 4]])
            >>> a.transpose()
            array([[1, 3],
                   [2, 4]])
            >>> a.transpose((1, 0))
            array([[1, 3],
                   [2, 4]])
            >>> a.transpose(1, 0)
            array([[1, 3],
                   [2, 4]])
        """
        pass

這兩者的源代碼還是又挺大區別的,雖然意思差不多

def transpose(a, axes=None):
    """
    Permute the dimensions of an array.
    Parameters
    ----------
    a : array_like
        Input array.
    axes : list of ints, optional
        By default, reverse the dimensions, otherwise permute the axes
        according to the values given.
    Returns
    -------
    p : ndarray
        `a` with its axes permuted.  A view is returned whenever
        possible.
    See Also
    --------
    moveaxis
    argsort
    Notes
    -----
    Use `transpose(a, argsort(axes))` to invert the transposition of tensors
    when using the `axes` keyword argument.
    Transposing a 1-D array returns an unchanged view of the original array.
    Examples
    --------
    >>> x = np.arange(4).reshape((2,2))
    >>> x
    array([[0, 1],
           [2, 3]])
    >>> np.transpose(x)
    array([[0, 2],
           [1, 3]])
    >>> x = np.ones((1, 2, 3))
    >>> np.transpose(x, (1, 0, 2)).shape
    (2, 1, 3)
    """
return _wrapfunc(a, 'transpose', axes)

還是看實驗吧:

In [73]: arr=np.arange(16).reshape(2,2,4)

In [74]: arr
Out[74]:
array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7]],

       [[ 8,  9, 10, 11],
        [12, 13, 14, 15]]])

In [75]: arr.transpose((1,0,2))   # 注意這個參數不帶key,不能寫axes=(1,0,2),若寫成這個,則報錯
Out[75]:
array([[[ 0,  1,  2,  3],
        [ 8,  9, 10, 11]],

       [[ 4,  5,  6,  7],
        [12, 13, 14, 15]]])

In [78]: np.transpose(arr, (1, 0, 2))  #這個參數可帶key,刻寫成axes=(1,0,2),若寫成這個,則通過
Out[78]:
array([[[ 0,  1,  2,  3],
        [ 8,  9, 10, 11]],

       [[ 4,  5,  6,  7],
        [12, 13, 14, 15]]])

 

三個維度的編號對應為(0,1,2),比如這樣,我們需要拿到7這個數字,怎么辦,肯定需要些三個維度的值,7的第一個維度為0,第二個維度為1,第三個3,

即坐標軸(0,1,2)的對應的坐標為(0,1,3)所以arr[0,1,3]則拿到了7

所以相當於把原來坐標軸[0,1,2]的轉置到[1,0,2],即把之前第三個維度轉為第一個維度,之前的第二個維度不變,之前的第一個維度變為第三個維度

理解了上面,再來理解swapaxes()就很簡單了,swapaxes接受一對軸編號,其實這里我們叫一對維度編號更好吧

arr.swapaxes(2,1)  就是將第三個維度和第二個維度交換

注意這個函數必須接受兩個參數,(兩個軸),不能寫成元組(2,1)的形式再傳入。

In [81]: arr.swapaxes(2,1)
Out[81]:
array([[[ 0,  4],
        [ 1,  5],
        [ 2,  6],
        [ 3,  7]],

       [[ 8, 12],
        [ 9, 13],
        [10, 14],
        [11, 15]]])

In [82]: arr.swapaxes((2,1))
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-82-24459d1e2980> in <module>()
----> 1 arr.swapaxes((2,1))

TypeError: swapaxes() takes exactly 2 arguments (1 given)

 

還是那我們的數字7來說,之前的索引是(0,1,3),那么交換之后,就應該是(0,3,1)

 

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM