(五)numpy知識學習2-python資料分析與機器學習實戰(學習筆記)

weixin_34402408發表於2018-05-02

文章原創,最近更新:2018-05-2

1.numpy矩陣基礎
2.numpy常用函式
3.矩陣常用操作
4.不同複製操作對比
5.排序和索引
課程來源: python資料分析與機器學習實戰-唐宇迪

1.numpy矩陣基礎

1.1 or 的判斷

現在說說與的操作,與的操作比較嚴格,&表示與的判斷.與的意思是當前的在陣列中的元素既等於10又等於5.我們來看一下下面的一個例子:

>>> vector=numpy.array([5,10,15,20])
>>> vector1=(vector==10)&(vector==5)
>>> vector1
array([False, False, False, False])

一個數不可能是既等於10又等於5,所以判斷出來的結果是全部等於False.

或的條件限制寬鬆了一些,對於一個元素可以是滿足這個條件,或者也可以滿足另外一個條件,用|來表示或.

>>> vector=numpy.array([5,10,15,20])
>>> vector2=(vector==10)|(vector==5)
>>> vector2
array([ True,  True, False, False])
>>> matrix = numpy.array([
            [5, 10, 15], 
            [20, 25, 30],
            [35, 40, 45]
         ])
>>> matrix1=matrix[:,1]==25
>>> matrix1
array([False,  True, False])
>>> matrix[matrix1,1]=10
>>> matrix
array([[ 5, 10, 15],
       [20, 10, 30],
       [35, 40, 45]])

1.2型別的改變

用astype函式更改資料的型別

>>> vector=numpy.array(["1","2","3"])
>>> vector.dtype
dtype('<U1')
>>> vector
array(['1', '2', '3'], dtype='<U1')
>>> vector=vector.astype(float)
>>> vector.dtype
dtype('float64')
>>> vector
array([1., 2., 3.])

1.3資料型別的計算

可按行,或按列用sum 或者min等方式對數值進行計算.

>>> vector = numpy.array([5, 10, 15, 20])
>>> vector.sum()
50
>>> vector.min()
5
>>> matrix = numpy.array([
                [5, 10, 15], 
                [20, 25, 30],
                [35, 40, 45]
             ])
>>> matrix.sum(axis=1)
array([ 30,  75, 120])
>>> matrix.sum(axis=0)
array([60, 75, 90])

2.numpy常用函式

2.1矩陣的屬性

構造了一個矩陣後,能否對矩陣進行變換?通過reshape函式更改numpy的維度形狀.

>>> import numpy as np
>>> np.arange(15)
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14])
>>> a=np.arange(15).reshape(3,5)
>>> a
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])

可通過shape知道矩陣的是由幾行幾列構成.

>>> a.shape
(3, 5)

可通過ndim知道矩陣的維度.一維or二維or其他

>>> a.ndim
2

dtype.name可以知道資料的型別的名稱

>>> a.dtype
dtype('int32')
>>> a.dtype.name
'int32'
>>> 

size知道矩陣型別有多少個元素?

>>> a.size
15

2.2矩陣的初始化

用zeros初始化值為0.三行四列(注意引數是個元組)

>>> np.zeros((3,4))
array([[0., 0., 0., 0.],
       [0., 0., 0., 0.],
       [0., 0., 0., 0.]])

用ones初始化為1

>>> np.ones((2,3,4),dtype=np.int32)
array([[[1, 1, 1, 1],
        [1, 1, 1, 1],
        [1, 1, 1, 1]],

       [[1, 1, 1, 1],
        [1, 1, 1, 1],
        [1, 1, 1, 1]]])

用exp以及sqtr分別對矩陣去e的指數以及開平方.

>>> import numpy as np
>>> B=np.arange(3)
>>> B
array([0, 1, 2])
>>> np.exp(B)
array([1.        , 2.71828183, 7.3890561 ])
>>> np.sqrt(B)
array([0.        , 1.        , 1.41421356])

floor向下取整,比如2.1取值為2,2.9取值也是2

>>> import numpy as np
>>> a=np.floor(10*np.random.random((3,4)))
>>> a
array([[8., 2., 6., 9.],
       [9., 6., 5., 2.],
       [0., 0., 1., 6.]])

>>> a.shape
(3, 4)

3.矩陣常用操作

3.1矩陣行列的轉換

用ravel函式將矩陣轉換為向量也就是一維.

a.ravel()
array([8., 2., 6., 9., 9., 6., 5., 2., 0., 0., 1., 6.])

用a.shape=(,)更改a為幾行幾列,與a.reshape()等價

>>> a.shape=(6,2)
>>> a
array([[8., 2.],
       [6., 9.],
       [9., 6.],
       [5., 2.],
       [0., 0.],
       [1., 6.]])
>>> a.reshape(6,2)
array([[8., 2.],
       [6., 9.],
       [9., 6.],
       [5., 2.],
       [0., 0.],
       [1., 6.]])

a.T對a進行轉置

>>> a
array([[8., 2.],
       [6., 9.],
       [9., 6.],
       [5., 2.],
       [0., 0.],
       [1., 6.]])
>>> a.T
array([[8., 6., 9., 5., 0., 1.],
       [2., 9., 6., 2., 0., 6.]])

reshape:有返回值,所謂有返回值,即不對原始多維陣列進行修改;
resize:無返回值,所謂有返回值,即會對原始多維陣列進行修改;

>>> a
array([[8., 2.],
       [6., 9.],
       [9., 6.],
       [5., 2.],
       [0., 0.],
       [1., 6.]])
>>> a.reshape(2,6)
array([[8., 2., 6., 9., 9., 6.],
       [5., 2., 0., 0., 1., 6.]])
>>> a
array([[8., 2.],
       [6., 9.],
       [9., 6.],
       [5., 2.],
       [0., 0.],
       [1., 6.]])
>>> a.resize((2,6))
>>> a
array([[8., 2., 6., 9., 9., 6.],
       [5., 2., 0., 0., 1., 6.]])
>>> 

.reshape(,-1)這個-1是前面定義好幾行,後面會自動幫你計算幾列,比如reshape(3,-1),

>>> a
array([[8., 2., 6., 9., 9., 6.],
       [5., 2., 0., 0., 1., 6.]])
>>> a.reshape(3,-1)
array([[8., 2., 6., 9.],
       [9., 6., 5., 2.],
       [0., 0., 1., 6.]])

3.2矩陣的拼接操作

可以分為按行拼接還是按列拼接
橫著拼,可以用.hstack((,))函式

>>> a=np.floor(10*np.random.random((2,2)))
>>> b=np.floor(10*np.random.random((2,2)))
>>> a
array([[0., 0.],
       [3., 1.]])
>>> b
array([[1., 7.],
       [7., 7.]])
>>> np.hstack((a,b))
array([[0., 0., 1., 7.],
       [3., 1., 7., 7.]])

豎著拼,可以用.vstack((,))函式

>>> a=np.floor(10*np.random.random((2,2)))
>>> b=np.floor(10*np.random.random((2,2)))
>>> a
array([[0., 0.],
       [3., 1.]])
>>> b
array([[1., 7.],
       [7., 7.]])

>>> np.vstack((a,b))
array([[0., 0.],
       [3., 1.],
       [1., 7.],
       [7., 7.]])

3.3矩陣的切分

矩陣的切分可分為按橫切分與豎切分
用.hsplit對矩陣進行橫切分

>>> a=np.floor(10*np.random.random((2,12)))
>>> a
array([[9., 8., 9., 3., 8., 8., 6., 3., 3., 2., 8., 3.],
       [4., 5., 7., 9., 0., 0., 8., 5., 6., 6., 9., 3.]])

>>> np.hsplit(a,3)
[array([[9., 8., 9., 3.],
       [4., 5., 7., 9.]]), array([[8., 8., 6., 3.],
       [0., 0., 8., 5.]]), array([[3., 2., 8., 3.],
       [6., 6., 9., 3.]])]

用.vsplit對矩陣進行橫切分


>>> a = np.floor(10*np.random.random((12,2)))
>>> a
array([[8., 1.],
       [3., 5.],
       [7., 7.],
       [9., 1.],
       [3., 1.],
       [9., 6.],
       [9., 3.],
       [3., 2.],
       [0., 0.],
       [9., 6.],
       [6., 6.],
       [3., 8.]])
>>> np.vsplit(a,3)
[array([[8., 1.],
       [3., 5.],
       [7., 7.],
       [9., 1.]]), array([[3., 1.],
       [9., 6.],
       [9., 3.],
       [3., 2.]]), array([[0., 0.],
       [9., 6.],
       [6., 6.],
       [3., 8.]])]
>>> 

如果按指定區域怎麼切分?
.hsplit(a,b)a是指待切分的矩陣,b是指定待切分的刀位置,是個元組(比如,(3,4),分別在3,4列各切一刀)
.vsplit(a,b)與.hsplit(a,b)方法一致

>>> a = np.floor(10*np.random.random((2,12)))
>>> a
array([[2., 6., 0., 5., 2., 2., 1., 3., 6., 9., 6., 8.],
       [4., 3., 2., 8., 1., 7., 8., 4., 9., 6., 7., 9.]])
>>> np.hsplit(a,(3,4))
[array([[2., 6., 0.],
       [4., 3., 2.]]), array([[5.],
       [8.]]), array([[2., 2., 1., 3., 6., 9., 6., 8.],
       [1., 7., 8., 4., 9., 6., 7., 9.]])]

4.不同複製操作對比

關於複製有3種方法

4.1等號賦值

>>> a=np.arange(12)
>>> a
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])
>>> b=a
>>> b
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])
>>> b is a
True

將b改成3行4列,當對b變化,a是否會發生變化?

>>> b
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])
>>> b.shape=(3,4)
>>> b
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])

>>> a.shape
(3, 4)

先把a的值賦給了b,b做了變化之後,a也會發生變化可以通過id值查詢是否兩者發生了相同的變化.(注意:id值相當於我們建立的時候,記憶體會分配一個唯一的區域.)

>>> id(a)
179563056
>>> id(b)
179563056

a,b兩值的id值一模一樣.說明a,b兩值名字不同,但是指向的東西是一樣的.改變a,b其中某個,兩者都會發生變化.

9945523-15a456eeaeff5987.png

4.2view操作

通過view操作,兩個值不一樣.

>>> a
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>> c=a.view()
>>> c
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>> c is a
False

將c變化,變成2行,6列的矩陣

>>> c.shape=(2,6)
>>> c
array([[ 0,  1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10, 11]])

看一下a的shape是否會發生改變?
a未發生變化,a與c是不一樣的

>>> a.shape
(3, 4)

將c矩陣的某個元素更改,a是否會更改?

>>> a
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>> c
array([[ 0,  1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10, 11]])

>>> c[0,4]=1234

>>> c
array([[   0,    1,    2,    3, 1234,    5],
       [   6,    7,    8,    9,   10,   11]])
>>> a
array([[   0,    1,    2,    3],
       [1234,    5,    6,    7],
       [   8,    9,   10,   11]])

>>> id(a)
179563056
>>> id(c)
179455120

通過上面可以看出,a的數值也發生了變化.因id不一樣,說明a,b指向不一樣,但是共用一套數值.

4.3copy複製

既讓複製的值不一樣,儲存的區域也不一樣,就使用copy複製.
相當於,一開始做了複製,然後是各自就各自,直接沒有任何的關係.這是最常用的方法.

d用a的值進行初始化,初始化之後就沒有關係.

>>> a
array([[   0,    1,    2,    3],
       [1234,    5,    6,    7],
       [   8,    9,   10,   11]])

>>> d=a.copy()
>>> d
array([[   0,    1,    2,    3],
       [1234,    5,    6,    7],
       [   8,    9,   10,   11]])
>>> d is a
False
>>> d[0,0]=9999

>>> d
array([[9999,    1,    2,    3],
       [1234,    5,    6,    7],
       [   8,    9,   10,   11]])
>>> a
array([[   0,    1,    2,    3],
       [1234,    5,    6,    7],
       [   8,    9,   10,   11]])

5.排序和索引

5.1尋找最大值

尋找矩陣哪個位置的值最大?
.argmax()函式尋找

>>> import numpy as np
>>> data= np.sin(np.arange(20)).reshape(5,4)
>>> data
array([[ 0.        ,  0.84147098,  0.90929743,  0.14112001],
       [-0.7568025 , -0.95892427, -0.2794155 ,  0.6569866 ],
       [ 0.98935825,  0.41211849, -0.54402111, -0.99999021],
       [-0.53657292,  0.42016704,  0.99060736,  0.65028784],
       [-0.28790332, -0.96139749, -0.75098725,  0.14987721]])
>>> ind=data.argmax(axis=0)
>>> ind
array([2, 0, 3, 1], dtype=int64)

結果是[2,0,1],矩陣按列計算,哪個值最大.

[2,0,1]這個索引值有什麼用,可以通過這個索引值具體尋找最大的值是多少?

>>> data_max=data[ind,range(data.shape[1])]
>>> data_max
array([0.98935825, 0.84147098, 0.99060736, 0.6569866 ])

ind這個值傳進來,相當於找到了這一行,再找列值,可以拿出最大的值.通過找索引的格式,在通過索引的實際標號拿出來.

5.2矩陣的擴充

用.tile函式進行擴充,可以對行與列都進行擴充,

>>> a=np.arange(0,40,10)
>>> a
array([ 0, 10, 20, 30])

>>> b=np.tile(a,(2,2))
>>> b
array([[ 0, 10, 20, 30,  0, 10, 20, 30],
       [ 0, 10, 20, 30,  0, 10, 20, 30]])

5.3矩陣的排序

用.sort()函式對矩陣排序

>>> a = np.array([[4, 3, 5], [1, 2, 1]])
>>> a
array([[4, 3, 5],
       [1, 2, 1]])
>>> b=np.sort(a,axis=1)
>>> b
array([[3, 4, 5],
       [1, 1, 2]])

用.argsort()求矩陣排序後的索引結果

>>> a = np.array([4, 3, 1, 2])
>>> j=np.argsort(a)
>>> j
array([2, 3, 1, 0], dtype=int64)
>>> a[j]
array([1, 2, 3, 4])

擴充:
1.先定義一個array資料

 import numpy as np
 x=np.array([1,4,3,-1,6,9])

2.現在我們可以看看argsort()函式的具體功能是什麼:

x.argsort()
輸出定義為y=array([3,0,2,1,4,5])。

我們發現argsort()函式是將x中的元素從小到大排列,提取其對應的index(索引),然後輸出到y。例如:x[3]=-1最小,所以y[0]=3,x[5]=9最大,所以y[5]=5。

上面這個不難理解,不熟悉的可以去python環境下自己嘗試。

相關文章