第2章 NumPy入門(2.1-2.2)_Python數據科學手冊學習筆記

第2章 NumPy入門(2.1-2.2)

根據<<數據科學手冊>> Python Data Science Handbook一書整理.

本章將詳細介紹NumPy(Numerical Python的簡稱)提供了高效存儲和操作密集數據緩存的藉口.在某些方面,NumPy數組和Python內置的列表類型非常相似.但是隨着數組在維度上變大,NumPy數組提供了更加高效的存儲和數據操作.NumPy數組幾乎是整個Python數據科學工具生態系統的核心.因此不管你對數據科學的哪個方面感興趣,花點時間學習如何有效使用NumPy都是非常值得的.

2.1 理解Python中的數據類型

2.1.5 創建幾個數組

import numpy as np

創建一個長度爲10的數組, 數組的值都是0

-是zeros, 不是zero
-此函數有啥作用?
np.zeros(10, dtype=int)     

創建一個3 * 5的浮點型數組, 數組的值都是1

3 * 5 表示3行*5列, 輸入代碼是圓括號本身是成對出現的, 如果手動添加或者剪切, 可能會導致錯誤

np.ones((3,5),dtype=int)
array([[1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1]])

創建一個3 * 5的浮點型數組, 數組的值都是3.14

np.full((3,5), 3.14)
array([[3.14, 3.14, 3.14, 3.14, 3.14],
       [3.14, 3.14, 3.14, 3.14, 3.14],
       [3.14, 3.14, 3.14, 3.14, 3.14]])

zeros,ones,full都是np下的函數, 可以創建數組.

-第一個參數告訴數組是多長, 或者是 n*k的數組 
-第二個參數,數值類型或者數值
np.zeros(10,dtype=str)
array(['', '', '', '', '', '', '', '', '', ''], dtype='<U1')
np.ones((3,3),dtype=int)
array([[1, 1, 1],
       [1, 1, 1],
       [1, 1, 1]])
np.full(9,520)
array([520, 520, 520, 520, 520, 520, 520, 520, 520])

創建一個線性序列, 從0開始,20結束,步長2

-和內置的range()函數類似
np.arange(0,20,2)
array([ 0,  2,  4,  6,  8, 10, 12, 14, 16, 18])

創建一個5個元素的數組,這5個數均勻分配到0-1中

-分位數嗎?
np.linspace(0,1,5)
array([0.  , 0.25, 0.5 , 0.75, 1.  ])
np.linspace(4,20,5)
array([ 4.,  8., 12., 16., 20.]

創建一個3*3,在0-1均勻分佈的隨機數組成的數組

-重點是0-1
-均勻分佈是什麼意思
np.random.random((3,3))
array([[0.39362852, 0.25206974, 0.88385296],
       [0.36547614, 0.34461809, 0.7989048 ],
       [0.7369659 , 0.21725593, 0.92850852]])
np.random.random((3*3))
array([0.28620252, 0.18814101, 0.51808316, 0.09341987, 0.78624051,
       0.89402738, 0.23804843, 0.04750264, 0.99956259])
np.random.random(5)
array([0.76369557, 0.88767111, 0.93486428, 0.54337144, 0.60357903])

創建一個3*3的,均值爲0,標準差爲1的

-正太分佈數組
np.random.normal(0,1,(3,3))
array([[ 0.90030434, -1.50711765,  0.97764385],
       [-0.31173987, -0.84110574, -0.10047986],
       [-0.43478952,  1.50298937,  0.73763183]])
np.random.normal(1.5,0.4,100)   #生成均值爲1.5,標準差爲0.4的100個數字.怎麼只顯示2位小數
array([1.22261068, 1.58441532, 1.88802132, 0.61486983, 1.87470827,
       2.25946452, 1.03590926, 1.33094771, 1.4062705 , 1.11332783,
       1.40300437, 1.56448717, 1.84108864, 1.889423  , 0.77694291,
       0.68180117, 1.30913434, 1.86453287, 1.47528384, 1.57611792,
       1.18340949, 1.52063669, 1.59611354, 1.42870295, 1.74599812,
       0.87469452, 0.74602807, 1.12764331, 1.25820621, 1.7901757 ,
       1.63144372, 1.53547336, 1.69190459, 1.56495873, 1.92058924,
       1.32189662, 1.81971028, 1.46019658, 2.35699722, 1.96548058,
       2.65711447, 0.89155833, 1.90166715, 1.88020944, 1.49726831,
       1.55377297, 1.25409672, 0.94901106, 0.94586283, 1.67326062,
       1.37021414, 1.63778177, 1.61532023, 1.01930684, 1.73838839,
       2.39846604, 1.1897899 , 0.98619697, 1.41209562, 1.66616348,
       1.67276465, 1.6177355 , 1.17221527, 1.81797366, 1.71753876,
       1.59004372, 2.19224441, 1.54545624, 1.62140601, 2.05344465,
       1.64692645, 1.51883407, 1.83548018, 1.29491494, 1.71556491,
       1.04304926, 1.04311419, 2.25142503, 1.65532576, 1.25867277,
       0.98532785, 0.76105179, 0.7609183 , 1.84616896, 1.95658462,
       2.37700902, 1.62810267, 1.62762617, 1.66713729, 1.87285054,
       1.88304677, 1.32029194, 1.2275771 , 1.38059868, 0.73470536,
       2.19813629, 1.96004672, 1.98630112, 1.74666125, 1.18260392])

創建一個3*3的,0-10區間的隨機數組成的數組

np.random.randint(0,10,(3,3))
array([4, 3, 4, 4, 8, 4])
np.random.randint(90,100,(2,2))
array([[94, 90],
       [92, 99]])

創建一個3*3的單位矩陣

np.eye(3)
array([[1., 0., 0.],
       [0., 1., 0.],
       [0., 0., 1.]])

創建一個由3個整數組成的未初始化的數組

-數組的值是內存空間的任意值?
np.empty(3)
array([1., 1., 1.])

2.1.6 NumPy中標準數據類型

NumPy數組包含同一類型的值. NumPy是在C語言基礎上開發的.

在構建數組時,可以用一個字符串參數指定數據類型

-NumPy中數據類型比Python中數據類型多,不加引號可能會報錯
np.zeros(10, dtype='int16')
np.zeros(10,dtype=np.int16)
np.zeros(10,dtype=int)
np.zeros(10,dtype=int16)      # int16是NumPy中數據類型,報錯
---------------------------------------------------------------------------

NameError                                 Traceback (most recent call last)

<ipython-input-38-ff102d8e3e0a> in <module>()
      2 np.zeros(10,dtype=np.int16)
      3 np.zeros(10,dtype=int)
----> 4 np.zeros(10,dtype=int16)


NameError: name 'int16' is not defined

NumPy中數據類型

-bool_ : 布爾值
-int_ : 默認整型
-intc : 同C語言中int相同
-intp : 用作索引的整型
-int8 : 字節,範圍從-128到127
-int16 :
-int32 :
-int64 :
-uint8 :
-uint16 :
-uint32 :
-uint64 :
-float_ :
-float16 :
-loat32 :
-float64 :
-complex_ :
-complex64 :
-complex128 :

2.2 NumPy數組基礎

Python中數據操作幾乎等同於NumPy中數組操作.Pandas工具也是構建在NumPy數組的基礎之上的.
    -數組的屬性(大小,形狀,存儲大小,數據類型)
    -數組的索引(獲取或者設置各個元素的值)
    -數組的切分
    -數組的變形
    -數組的拼接與分裂

2.2.1 數組的屬性

import numpy as np
np.random.seed(0)     #設置隨機數種子值,
x1 = np.random.randint(10,size=6)    # 還可以寫成 np.random.randint(0,10,6)
np.random.randint(0,10,6)
x2 = np.random.randint(10,size=(3,4))
x3 = np.random.randint(10,size=(3,4,5))
print(x3)
[[[4 3 0 3 5]
  [0 2 3 8 1]
  [3 3 3 7 0]
  [1 9 9 0 4]]

 [[7 3 2 7 2]
  [0 0 4 5 5]
  [6 8 4 1 4]
  [9 8 1 1 7]]

 [[9 9 3 6 7]
  [2 0 3 5 9]
  [4 4 6 4 4]
  [3 4 4 8 4]]]

每個數組都有數組的ndim(數組的維度),shape(數組每個維度的大小),size(數組的總大小)和dtype(數組的數據類型)
其他: itemsize(每個元素字節大小), nbytes(總字節大小). 什麼東東?

print('x3的維度是:',x3.ndim)
print('x3的每個維度大小是:',x3.shape)    # 每個維度的大小是從外向內數?
print('x3的總大小是:',x3.size)
print('x3的數據類型是:',x3.dtype)
print('x3的字節大小是:',x3.itemsize,"bytes")
print('x3的總字節大小是:',x3.nbytes,'bytes')
x3的維度是: 3
x3的每個維度大小是: (3, 4, 5)
x3的總大小是: 60
x3的數據類型是: int32
x3的字節大小是: 4 bytes
x3的總字節大小是: 240 bytes

2.2.2 數組的索引: 獲取單個元素

一維數組

np.random.seed(0)
x1 = np.random.randint(10,size=6)     # 這樣生成的6位隨機數居然和書本上的一樣
print(x1)
print(x1[0])                          #第一位
print(x1[4])
print(x1[-1])       #最後一位
[5 0 3 3 7 9]
5
7
9

二維數組

print(x2)
print(x2[0,0])
print(x2[2,2])
print(x2[2,-1])
[[8 8 1 6]
 [7 7 8 1]
 [5 9 8 9]]
8
8
9

修改某個值數據. 數組是有數據類型的, 如果加入的數值類型不一樣, 會自動變換

x2[0,0] = "100"    #如果是字符型字符串則報錯
x2[2,2] =  3.14
x2
array([[100,   8,   1,   6],
       [  7,   7,   8,   1],
       [  5,   9,   3,   9]])

三維數組

x3
array([[[   4,    3,    0,    3,    5],
        [   0,    2,    3,    8,    1],
        [   3,    3,    3,    7,    0],
        [   1,    9,    9,    0,    4]],

       [[   7,    3,    2,    7,    2],
        [   0,    0,    4,    5,    5],
        [   6, 1000,    4,    1,    4],
        [   9,    8,    1,    1,    7]],

       [[   9,    9,    3,    6,    7],
        [   2,    0,    3,    5,    9],
        [   4,    4,    6,    4,    4],
        [   3,    4,    4,    8,    4]]])
print(x3[0,0,0])
print(x3[1,2,1])    # 二維 ,第3行,第2列
x3[1,2,1]=1000
print(x3)
4
8
[[[   4    3    0    3    5]
  [   0    2    3    8    1]
  [   3    3    3    7    0]
  [   1    9    9    0    4]]

 [[   7    3    2    7    2]
  [   0    0    4    5    5]
  [   6 1000    4    1    4]
  [   9    8    1    1    7]]

 [[   9    9    3    6    7]
  [   2    0    3    5    9]
  [   4    4    6    4    4]
  [   3    4    4    8    4]]]

2.2.3 數組的切片: 獲取子數組

NumPy中切片語法和Python中列表的切片語法相同, 用冒號(:)分開.
x[start:stop:step]
如果以上三個參數都沒有設置,則使用默認值 start=0, stop=維度的大小, 和step=1

x = np.arange(10)
x
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
x[:5]   # 前5個
array([0, 1, 2, 3, 4])
x[5:]
array([5, 6, 7, 8, 9])
x[4:7]
array([4, 5, 6])

每隔一個數字

x[::2]   
array([0, 2, 4, 6, 8])
x[1::2]
array([1, 3, 5, 7, 9])

一維數組逆序

x[::-1]
array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])

二維數組

x2
array([[8, 8, 1, 6],
       [7, 7, 8, 1],
       [5, 9, 8, 9]])
x2[:2,:3]     
array([[100,   8,   1],
       [  7,   7,   8]])

看見冒號(?,表示數組切片

x2[:,::2]   # 所有行, 每隔一列
array([[8, 1],
       [7, 8],
       [5, 8]])
x2[::-1,::-1]    # 顛倒順序
array([[9, 8, 9, 5],
       [1, 8, 7, 7],
       [6, 1, 8, 8]])

三維數組

x3
array([[[   4,    3,    0,    3,    5],
        [   0,    2,    3,    8,    1],
        [   3,    3,    3,    7,    0],
        [   1,    9,    9,    0,    4]],

       [[   7,    3,    2,    7,    2],
        [   0,    0,    4,    5,    5],
        [   6, 1000,    4,    1,    4],
        [   9,    8,    1,    1,    7]],

       [[   9,    9,    3,    6,    7],
        [   2,    0,    3,    5,    9],
        [   4,    4,    6,    4,    4],
        [   3,    4,    4,    8,    4]]])
x3[::-1,::-1,::-1]
array([[[   4,    8,    4,    4,    3],
        [   4,    4,    6,    4,    4],
        [   9,    5,    3,    0,    2],
        [   7,    6,    3,    9,    9]],

       [[   7,    1,    1,    8,    9],
        [   4,    1,    4, 1000,    6],
        [   5,    5,    4,    0,    0],
        [   2,    7,    2,    3,    7]],

       [[   4,    0,    9,    9,    1],
        [   0,    7,    3,    3,    3],
        [   1,    8,    3,    2,    0],
        [   5,    3,    0,    3,    4]]])
x3
array([[[   4,    3,    0,    3,    5],
        [   0,    2,    3,    8,    1],
        [   3,    3,    3,    7,    0],
        [   1,    9,    9,    0,    4]],

       [[   7,    3,    2,    7,    2],
        [   0,    0,    4,    5,    5],
        [   6, 1000,    4,    1,    4],
        [   9,    8,    1,    1,    7]],

       [[   9,    9,    3,    6,    7],
        [   2,    0,    3,    5,    9],
        [   4,    4,    6,    4,    4],
        [   3,    4,    4,    8,    4]]])
x3[::,0,::]   # 第一維度全選, 第二維度選第1行,第三維度全選
array([[4, 3, 0, 3, 5],
       [7, 3, 2, 7, 2],
       [9, 9, 3, 6, 7]])
x3[::2,::2,::2]
array([[[4, 0, 5],
        [3, 3, 0]],

       [[9, 3, 7],
        [4, 6, 4]]])

獲取數組的單行或者單列

x2
array([[8, 8, 1, 6],
       [7, 7, 8, 1],
       [5, 9, 8, 9]])
x2[:,0]   # 第1列
array([8, 7, 5])
x2[:,2]  # 第3列
array([1, 8, 8])
x2[0,:]  # 第1行   
x2[0]    #獲取行時簡寫表示方法, 對列不適用
array([8, 8, 1, 6])
x2[1,:]
array([7, 7, 8, 1])

NumPy數組切片和Python列表切片的不同之處: NumPy數組切片返回的是數組的試圖,而不是數值數據的副本. 在Pythong列表中,切片是值得副本.

-副本 : 可以理解爲複製了一份和原來的不一樣了.
-視圖 : 可以理解爲超鏈接,修改還是改的原來的路徑(文件)
-好處是,當處理大量的數據集時, 只需要修改切片即可修改原數據
print(x2)
[[100   8   1   6]
 [  7   7   8   1]
 [  5   9   8   9]]

從中抽取一個2*2的子數組

x2_sub = x2[::2,::2]
print(x2_sub)
[[100   1]
 [  5   8]]
x2_sub[0,0] = 100
x2
array([[100,   8,   1,   6],
       [  7,   7,   8,   1],
       [  5,   9,   8,   9]])

數組切片只能形成數組的視圖, 那如果要新建副本,用copy()方法

x2_sub = x2[::2,::2].copy()
print(x2)
print('*'*20)
print(x2_sub)
[[100   8   1   6]
 [  7   7   8   1]
 [  5   9   8   9]]
********************
[[100   1]
 [  5   8]]
x2_sub[1,1] = 99
print(x2)
print("*"*20)
print(x2_sub)
print('*'*20)
print(x2)
[[100   8   1   6]
 [  7   7   8   1]
 [  5   9   8   9]]
********************
[[100   1]
 [  5  99]]
********************
[[100   8   1   6]
 [  7   7   8   1]
 [  5   9   8   9]]

2.2.4 數組的變形

最常用的方法是用reshape()方法實現.
例如:期望將數字1-9,放入3*3的矩陣中,可採用如下方法:

-reshape()  數組的屬性
-newaxis()  np的屬性
np.arange(1,10).reshape(3*3)    #錯
np.arange(1,10).reshape(3,3)
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])

原始數組的大小必須和變形後數組大小一致. reshape返回原數組的一個視圖

大小不一致的情況

a1 = ([1,2,3,4,5,6,7,8])
np.a1.reshape(3,3)     # 表示方法錯. np沒有a1屬性
---------------------------------------------------------------------------

AttributeError                            Traceback (most recent call last)

<ipython-input-48-75353fe7632b> in <module>()
      1 a1 = ([1,2,3,4,5,6,7,8,9])
----> 2 np.a1.reshape(3,3)


AttributeError: module 'numpy' has no attribute 'a1'
a1 = array([1,2,3,4,5,6,7,8])    # 數組array 前面必須帶np
a1.reshape((3,3))     
---------------------------------------------------------------------------

NameError                                 Traceback (most recent call last)

<ipython-input-52-202d01b8f390> in <module>()
----> 1 a1 = array([1,2,3,4,5,6,7,8])
      2 a1.reshape((3,3))     # 表示方法錯


NameError: name 'array' is not defined
a1 = np.array([1,2,3,4,5,6,7,8,9])
a1.reshape((3,3))     
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])
np.array([1,2,3,4,5,6,7,8]).reshape(3,3)     # 少了不行
---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

<ipython-input-49-1a37bef6142d> in <module>()
----> 1 np.array([1,2,3,4,5,6,7,8]).reshape(3,3)


ValueError: cannot reshape array of size 8 into shape (3,3)
np.array([1,2,3,4,5,6,7,8,9,10]).reshape(3,3)  # 多了也不行
---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

<ipython-input-50-0a4d36c4b6a6> in <module>()
----> 1 np.array([1,2,3,4,5,6,7,8,9,10]).reshape(3,3)


ValueError: cannot reshape array of size 10 into shape (3,3)
x = np.array([1,2,3])   #一維數組
x.reshape(1,3)    #  變成1行3列的二維數組
array([[1, 2, 3]])
x[np.newaxis,:]
array([[1, 2, 3]])
x.reshape(3,1)
array([[1],
       [2],
       [3]])
x[:,np.newaxis]    # newaxis 屬於關鍵字
array([[1],
       [2],
       [3]])

2.2.5 數組的拼接和分裂

多個數組合併成一個或者一個數組拆分成多個

-np.concatenate():將數組元組和數組列表作爲第一個參數
-np.vstack()
-np.hstack()
x = np.array([1,2,3])
y = np.array([3,2,1])
x_y = np.concatenate([x,y])
print(x_y)
print(x_y.ndim)
[1 2 3 3 2 1]
1
z = [99,99,99]  # 不用 np.array([99,99,99])
np.concatenate([x,y,z])
array([ 1,  2,  3,  3,  2,  1, 99, 99, 99])
x1 = [99,99,99]   # 這是一個列表
x2 = np.array([99,99,99])
print(x1 == x2)
print(x1 is x2)
[ True  True  True]
False

二維數組的拼接

#沿着第一個軸拼接?   沿着第一個軸拼接,爲什麼是縱向
import numpy as np
x1 = np.array([[1,2,3],
               [4,5,6]])
np.concatenate([x1,x1])   # 中括號不能少
array([[1, 2, 3],
       [4, 5, 6],
       [1, 2, 3],
       [4, 5, 6]])
# 沿着第二個軸拼接, 沿着水平方向
np.concatenate([x1,x1],axis=1)    # 注意中括號和圓括號的位置
array([[1, 2, 3, 1, 2, 3],
       [4, 5, 6, 4, 5, 6]])

沿着固定維度處理數組時, 使用

np.vstack(垂直棧)
np.hstack(水平棧)函數更簡潔 ??

x1 = np.array([1,2,3])
x2 = np.array([[9,8,7],
              [2,5,9]])
#垂直棧數組
np.vstack([x1,x2])
array([[1, 2, 3],
       [9, 8, 7],
       [2, 5, 9]])
#水平棧數組
x3 = np.array([[99],
              [99]])
np.hstack([x3,x2])
array([[99,  9,  8,  7],
       [99,  2,  5,  9]])

數組的分裂

-np.split()
-np.hsplit()
-np.vsplit()
x = [1,2,3,99,99,3,2,1]  # 這不是一個序列碼
x1,x2,x3 = np.split(x,(3,5))    # 注意 x 和[3,5]的位置與括號,也可以用(3,5)
print(x1,x2,x3)
[1 2 3] [99 99] [3 2 1]
x1 = np.arange(16).reshape(4,4)
up,low = np.vsplit(x1,2)     # [2]也可以寫成(2),也可以不加括號 ?
print(up)
print('*'*20)
print(low)
print('*'*20)
print(x1)
[[0 1 2 3]
 [4 5 6 7]]
********************
[[ 8  9 10 11]
 [12 13 14 15]]
********************
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]
 [12 13 14 15]]
left,right = np.hsplit(x1,[2])     # 爲什麼此處的中括號必須 
print(left)
print('*'*20)
print(right)
[1 2]
********************
[3]
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章