Python數據處理:Numpy 學習筆記

Python數據處理:IPython使用學習筆記
Python數據處理:Numpy 學習筆記
Python數據處理:Pandas 學習筆記


NumPy快速入門手冊》寫得很好,也推薦閱讀


一. numpy

1. 介紹

2. numpy引用

"""numpy的主要對象是一個規範格式的多維數組"""
import numpy as np

二. 創建numpy數組

1. 通過list、tuple或其他序列,創建數組

### 通過list、tuple或其他序列,創建數組
data = np.array([[1, 2, 3], [4, 5, 6]])     # 生成np的數組,注意入參不能是多個元素:如np.array(1,2,3,4),否則會報錯
data2 = np.array([[1, 3], [5, 7], [9, 11]], dtype=complex)     # 可以直接指定數據類型dtype
print(data2)
'''  可以看到數據格式轉成了複數
[[  1.+0.j   3.+0.j]
 [  5.+0.j   7.+0.j]
 [  9.+0.j  11.+0.j]]
'''

2. 創建特定格式和內容的數組

a. 全一數組
# 全一數組
one_np = np.ones([3,2], dtype=int)           # 創建全爲1的二維數組,第一個參數shape決定了數組的格式
print(one_np)
'''
[[1 1]
 [1 1]
 [1 1]]
'''
b. 全零數組
# 全零數組
zero_np = np.zeros([2, 3, 2], dtype=float)    # 創建了一個三維數組,每個數組元素都是0
print(zero_np)
'''
[[[ 0.  0.]
  [ 0.  0.]
  [ 0.  0.]]
 [[ 0.  0.]
  [ 0.  0.]
  [ 0.  0.]]]
'''
c. 空隨機數組
# 空隨機數組
random_np = np.empty([2, 2])    # 根據系統的狀態隨機生成一些佔位元素,數組完全是隨機的
print(random_np)
''' 
[[  1.33511562e-306   6.23040373e-307]
 [  1.20161730e-306   1.02360527e-306]]
'''

3. 數字序列數組

### 數字序列數組
# arange()      起點start + 終點stop(不包含) + 總共節點數step
data3 = np.arange(1, 9, 2)      # 類似於range()函數, 一維數組
print(data3)                    # [1 3 5 7]

# linspace()    起點start + 終點stop(包含) + 總共節點數num
data4 = np.linspace(0, 5)       # linspace(start, stop, num=50)生成從起點到終點(包括),均勻間隔的一維數組。
                                # 其中num默認爲50,表示數組長度(因此元素間隔寬度爲(stop - start)/num )
print(data4)
'''
array([ 0.        ,  0.10204082,  0.20408163,  0.30612245,  0.40816327,
        0.51020408,  0.6122449 ,  0.71428571,  0.81632653,  0.91836735,
        1.02040816,  1.12244898,  1.2244898 ,  1.32653061,  1.42857143,
        1.53061224,  1.63265306,  1.73469388,  1.83673469,  1.93877551,
        2.04081633,  2.14285714,  2.24489796,  2.34693878,  2.44897959,
        2.55102041,  2.65306122,  2.75510204,  2.85714286,  2.95918367,
        3.06122449,  3.16326531,  3.26530612,  3.36734694,  3.46938776,
        3.57142857,  3.67346939,  3.7755102 ,  3.87755102,  3.97959184,
        4.08163265,  4.18367347,  4.28571429,  4.3877551 ,  4.48979592,
        4.59183673,  4.69387755,  4.79591837,  4.89795918,  5.        ])
'''

4. 隨機數

a. np.random.rand 生成[0,1)區間內平均分佈的數組,參數爲維度
### 隨機數
# 生成[0,1)區間內平均分佈的數組,參數爲維度
data5 = np.random.rand(2, 3, 5)
print(data5)
'''
[[[ 0.11460522  0.78475528  0.41318688  0.9830661   0.23276821]
  [ 0.31333353  0.99497377  0.31270973  0.55575352  0.30095844]
  [ 0.83803498  0.07725709  0.60617707  0.17494517  0.7324532 ]]
 [[ 0.03576562  0.84033749  0.81820702  0.46633063  0.06972207]
  [ 0.00538072  0.44754953  0.23233634  0.78536293  0.43381988]
  [ 0.85224057  0.40323818  0.07592376  0.23596046  0.49922436]]]
'''
b. np.random.randn 生成標準正態分佈規律的數組(數出現的概率滿足標準正太分佈),參數爲維度
# 生成標準正態分佈規律的數組(數出現的概率滿足標準正太分佈),參數爲維度
data6 = np.random.randn(2, 3, 5)
print(data6)
'''
[[[-0.51493028  1.78516665 -0.38657793  0.70038985 -1.24254944]
  [-0.80613041  0.63745159  0.74201648  0.39451194 -0.94476024]
  [-0.47833675 -0.92092758  1.01658297  0.85712149 -0.21944187]]
 [[ 1.3295873  -0.10871527  0.31088519 -0.60094403  1.80437504]
  [-0.3851662  -0.26422884  1.03784294 -0.44199909  0.83116801]
  [-0.03563173 -0.66946972  0.45256832  0.17121998  0.2120946 ]]]
'''
c. 生成指定範圍的隨機數
# 生成指定範圍的隨機整數
np.random.randint(1, 7, 10)         # 開區間,不可能取7 ,array([5, 3, 6, 1, 6, 1, 6, 5, 4, 3])
np.random.random_integers(1,7,10)   # 閉區間,可以取到7  array([5, 1, 1, 7, 7, 2, 6, 5, 1, 2])
np.random.random()                  # [0,1)內隨機數 本例:0.3825271804785396
d. np.random.choice 隨機選擇
# 隨機選擇
np.random.choice(10,size=2)         # array([7, 4])
np.random.choice(10,size=(3,4))     # 設置shape
'''
array([[4, 9, 5, 7],
       [6, 6, 5, 1],
       [6, 5, 5, 0]])
'''

np.random.choice(['a','b','c'],size=[2,2])      # 從給出的list中隨機選擇生成數組
'''
array([['c', 'b'],
       ['c', 'b']],
      dtype='<U1')
'''

二. 數組的屬性

"""數組的屬性"""
data = np.array([[1, 2, 3], [4, 5, 6]])     
data.ndim       # 數組的維度 本例:2
data.shape      # 數組的形狀,返回一個元組,表示各個方向的長度,元組本身的長度等於數組的維度. 本例:(2, 3)
data.size       # 數組的大小,等於shape元組內各個元素的乘積, 本例:6
data.dtype      # 數組內部元素的數據類型, 本例:dtype('int32')
data.itemsize   # 數組內元素佔計算機內存的大小(多少個Byte), 本例:4
data.data       # 數組在內存中的地址,一般很少用,本例:<memory at 0x00000000070AC1F8>

三. 數組維度及元素類型轉換

1. 重新修改維度(常用)

### 重新修改維度(常用)
data_shaped1 = data.reshape(3,2)
print(data_shaped1)
'''
[[1 2]
 [3 4]
 [5 6]]
'''

# 利用arrange() 和 reshape() 生成多維數組
data_shaped3 = np.arange(24).reshape(3, -1, 4)   #如果某一個方向設爲-1,則會自動計算
print(data_shaped3)
''' 可以看到,第二維度被自動計算爲2
[[[ 0  1  2  3]
  [ 4  5  6  7]]
 [[ 8  9 10 11]
  [12 13 14 15]]
 [[16 17 18 19]
  [20 21 22 23]]]
'''

### resize()
# 與 reshape()相似,不過resize()會修改原數組

2. np數組轉換爲list

### 轉換爲list
list_np = one_np.tolist()           # [[1, 1], [1, 1], [1, 1]]

3. np.astype() 轉換元素類型

### 轉換類型 astype() 在轉換中,可能會損失精度
data2_int = data2.astype(int)           # 元素數據類型,從原先的複數complex轉換爲int
print(data2_int)
'''
[[ 1  3]
 [ 5  7]
 [ 9 11]]
'''

4. 數組轉置

### 數組轉置
np.transpose(data_shaped1)
'''
array([[1, 3, 5],
       [2, 4, 6]])
'''

# 多維數組轉置
np.transpose(data_shaped3)        # 多維數組轉置,就是座標的reverse,然後組成新數組,注意數據交換
'''
array([[[ 0,  8, 16],       d[0,0,0], d[1,0,0], d[2,0,0]
        [ 4, 12, 20]],      d[0,1,0], d[1,1,0], d[2,1,0]
       [[ 1,  9, 17],       d[0,0,1], d[1,0,1], d[2,0,1]
        [ 5, 13, 21]],      d[0,1,1], d[1,1,1], d[2,1,1]
       [[ 2, 10, 18],       d[0,0,2], d[1,0,2], d[2,0,2]
        [ 6, 14, 22]],      d[0,1,2], d[1,1,2], d[2,1,2]
       [[ 3, 11, 19],       d[0,0,3], d[1,0,3], d[2,0,3]
        [ 7, 15, 23]]])     d[0,1,3], d[1,1,3], d[2,1,3]
'''

5. 轉換一維數組

### ravel() 逐行取元素並返回一個一維數組
print(np.ravel(data_shaped3))       # [ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23]

四. 數組的完全不復制(全部引用)、指代(局部引用)、深度複製

1. 完全不復制

### 1. 完全不復制
a = np.arange(4)
b = np.arange(4)
b is a                  # b和a現在還不是同一引用,爲False
b = a
b is a                  # b和a是同一引用,爲True
a.shape                 # 此時是(4,)
b.shape = (2,2)         # 因爲是同一引用,所以也會修改a的形狀
a.shape                 # 變爲(2, 2)

2. 指代 (切片也是如此)

### 2. 指代 (切片也是如此)
a = np.arange(12,24).reshape(3,4)
b = a.view()            # 返回一個指代,但還是引用了同一數組
b is a                  # False

b[1,2] = 678
print(a)
''' 可以看到a[1,2]也變成了678
[[ 12  13  14  15]
 [ 16  17 678  19]
 [ 20  21  22  23]]
'''

3. 深度複製

### 3. 深度複製
a = np.arange(12,24).reshape(3,4)
b = a.copy()

b is a                  # False
b[1,1] = 111
print(b)
'''
[[ 12  13  14  15]
 [ 16 111  18  19]
 [ 20  21  22  23]]
'''
print(a)
''' a 沒變
[[12 13 14 15]
 [16 17 18 19]
 [20 21 22 23]]
'''

五. 數組取值及分片

1. 多維數組通過索引取某一元素

### 多維數組通過索引取某一元素
c = np.arange(12).reshape(3, 4)     # 創建一個3*4的二維數組
print(c)
'''
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
'''
c[1,3]                  # 取第二行第四列的元素,本例:7
c[1][3]                 # 取第二行第四列的元素,本例:7

2. 一維數組分片 arr[i:j:k]

i決定起始,j決定結束,k決定步進,都可以爲負數,其中k爲負則倒序取值

### 一維數組分片  arr[i:j:k]  i決定起始,j決定結束,k決定步進,都可以爲負數,其中k爲負則倒序取值
b = np.arange(1,20,2)
b                       # array([ 1,  3,  5,  7,  9, 11, 13, 15, 17, 19])
b[2]                    # 取第三項的元素, 本例:5
b[2:4]                  # 取第三、四項的子分片,本例:array([5, 7])
b[:5:2]                 # 在原數組前五項中,步進爲2的取數組成新數組,本例:array([1, 5, 9])
b[-3:1:-2]              # 從倒數第三項('15')開始,從後向前步進2格取值,直到第二項('3',不包含此項) 本例:array([15, 11,  7])


## 注意:雖然語法相似,但不同於list的分片(創建副本),np的分片是不創建副本的,修改分片中的元素,會影響到原數組的元素
sub_b = b[2:7:3]        # sub_b = array([ 5, 11])
sub_b[1] = 1            # 此時sub_b變爲了array([5, 1])
b                       # 同時原數組也發生了變化:array([ 1,  3,  5,  7,  9,  1, 13, 15, 17, 19])

### 如果想創建絕對的副本,則要用copy()
b = np.arange(1,20,2)
duplicate_b = b[2:7:3].copy()           # duplicate_b = array([ 5, 11]), 使用copy創建副本
duplicate_b[1] = 1                      # 此時duplicate_b變爲了array([5, 1])
b                       # 原數組沒有變:array([ 1,  3,  5,  7,  9, 11, 13, 15, 17, 19])

4. 多維數組分片

### 多維數組分片
c = np.arange(12).reshape(3, 4)     # 創建一個3*4的二維數組
print(c)
'''
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
'''
sub_c = c[1:3,1:3]      # 取2、3行和2、3列的子數組
print(sub_c)
'''
[[ 5  6]
 [ 9 10]]
'''

## 多維數組倒序分片
sub_c = c[::-2,1:3]      # 取所有行步進爲-2(從後向前)和2、3列組成的子數組
print(sub_c)
'''
[[ 9 10]            # 先取的第三行的9,10
 [ 1  2]]           # 再取的第一行的1,2 
'''

使用分片,批量修改元素及順序

### 使用分片,批量修改元素(因爲只是引用)
b = np.arange(1,20,2)   # array([ 1,  3,  5,  7,  9, 11, 13, 15, 17, 19])
b[1:9:2] += 1           # 從第2項到第9項,步進爲2的數都自增1
b                       # array([ 1,  4,  5,  8,  9, 12, 13, 16, 17, 19])
### 拓展:重新排序
c = b[[0,2,1]]
print(c)
'''
[[10 11 12 13]
 [18 19 20 21]          第二行和第三行交換了順序
 [14 15 16 17]]
'''

d = b[:,[3,0,-2,1]]
print(d)
''' 列上交換了順序
[[13 10 12 11]
 [17 14 16 15]
 [21 18 20 19]]
'''

六. 高級索引

1. 整數索引

a. 數組arr_index爲索引,從一維數組array中篩選出新的數組
## 數組arr_index爲索引,從一維數組array中篩選出新的數組
a = np.arange(10,20)            # a: array([10, 11, 12, 13, 14, 15, 16, 17, 18, 19])
arr_index = np.array(([3,4,5],[1,2,3]))
a_new = a[arr_index]
print(a_new)
''' 可以看到取的數組的格式跟arr_index一致,每個元素爲原數組在索引arr_index[i]處的值
[[13 14 15]         a[3]=13, a[4]=14, a[5]=15
 [11 12 13]]        a[1]=11, a[2]=12, a[3]=13
'''
b. 數組arr_index爲索引,從多維數組array中篩選出新的數組
## 數組arr_index爲索引,從多維數組array中篩選出新的數組
b = np.arange(10,22).reshape(3,4)
print(b)
"""
[[10 11 12 13]
 [14 15 16 17]
 [18 19 20 21]]
"""
arr_index = np.array([[0,2,1],[1,2,0]])
e = b[arr_index]
print(e)
''' 本質上與一維數組和多維索引的結果類似,整體數組的形狀還是按照索引arr_index的形狀,
只是這裏的索引搜出來的元素不是簡單數據,而是一維數組,所以整個結果數組擴充爲了三維數組
[[[10 11 12 13]         b[0]=[10 11 12 13]
  [18 19 20 21]         b[2]=[18 19 20 21]  
  [14 15 16 17]]        b[1]
 [[14 15 16 17]         b[1]
  [18 19 20 21]         b[2]
  [10 11 12 13]]]       b[0]
'''
c. 列表、元組list_index爲索引,從多維數組array中篩選出新的數組
## 列表、元組list_index爲索引,從多維數組array中篩選出新的數組
b = np.arange(10,22).reshape(3,4)
print(b)
'''
[[10 11 12 13]
 [14 15 16 17]
 [18 19 20 21]]
'''
list_index = ([0,2,1],[1,2,0])       # 注意這裏是list、tuple或者其他簡單序列,不是np.array
b_new = b[list_index]
print(b_new)
''' 通過索引來取元素組成新的結果
[11 20 14]          a[0,1]=11, a[2,2]=20, a[1,0]=14

2. 布爾索引

a. 布爾索引的意義
###  布爾索引  通過True/False的數組,來索引數組
m = np.random.rand(30).reshape(10, 3)       # 創建一個10 * 3 的二維數組
print(m)
'''
[[ 0.64877021  0.72179137  0.56534942]
 [ 0.66861906  0.99436     0.09971997]
 [ 0.71550022  0.39179217  0.69544798]
 [ 0.76190541  0.71990526  0.5056289 ]
 [ 0.09218896  0.20907768  0.53118   ]
 [ 0.04977315  0.79410303  0.86770033]
 [ 0.39507158  0.42490585  0.48495278]
 [ 0.18026899  0.47850156  0.13560222]
 [ 0.11837795  0.67394728  0.7619298 ]
 [ 0.23708205  0.93920253  0.79138269]]
'''

m_select = m[[True,False,False,False,True,True,False,False,False,False]]        # 總共10個Boolean值,對應m的10行
print(m_select)
''' 通過True值,篩選出第一行、第五、六行的數據組成子數組
[[ 0.64877021  0.72179137  0.56534942]
 [ 0.09218896  0.20907768  0.53118   ]
 [ 0.04977315  0.79410303  0.86770033]]
'''

# 這樣乍一看覺得用布爾值多此一舉,用數篩選更方便,但如果有兩個數組,之間存在對應關係,布爾值搜索就十分方便
n = np.array(['小明','小紅','李白','小明','小明','李白','小紅','張偉','李白','張偉'])    # n中有10個人,對應m的十行數據

# 現在我們要篩選出屬於'小紅'的數據
m_select2 = m[n=='小紅']
print(m_select2)
''' 篩選出屬於小紅的第二行、第七行數據
[[ 0.66861906  0.99436     0.09971997]
 [ 0.39507158  0.42490585  0.48495278]]
'''
b. 布爾索引判斷的拓展
## 還可以再用切片或者篩選
m_select3 = m[n=='小紅',1]            # 篩選出第二列的數據
print(m_select3)                    # [ 0.99436     0.42490585]

## 與或非運算
m_select4 = m[n!='小紅',:2]        # 篩選出不是小紅的前兩列數據
print(m_select4)
'''
[[ 0.64877021  0.72179137]
 [ 0.71550022  0.39179217]
 [ 0.76190541  0.71990526]
 [ 0.09218896  0.20907768]
 [ 0.04977315  0.79410303]
 [ 0.18026899  0.47850156]
 [ 0.11837795  0.67394728]
 [ 0.23708205  0.93920253]]
'''

m_select5 = m[(n=='小紅')|(n=='李白')]        # 篩選出小紅或者李白的數據
print(m_select5)
'''
[[ 0.66861906  0.99436     0.09971997]
 [ 0.71550022  0.39179217  0.69544798]
 [ 0.04977315  0.79410303  0.86770033]
 [ 0.39507158  0.42490585  0.48495278]
 [ 0.11837795  0.67394728  0.7619298 ]]
'''

七. 數組元素替換和填充

1. 布爾索引

"""數組元素替換和填充   布爾索引 + np.where() """
### 通過布爾索引,實現元素替換與填充
x = np.array([[1,2],[np.nan, 3],[np.nan, np.nan]])
print(x)
'''
[[  1.   2.]
 [ nan   3.]
 [ nan  nan]]
'''

np.isnan(x)
'''
array([[False, False],
       [ True, False],
       [ True,  True]], dtype=bool)
'''
x[np.isnan(x)]              # 篩選出是nan元素組成新一維數組, array([ nan,  nan,  nan])
x[np.isnan(x)] = 0          # 將x中是nan的元素,都替換爲0,通過布爾索引實現替換元素的功能
print(x)
'''
[[ 1.  2.]
 [ 0.  3.]
 [ 0.  0.]]
'''
x[~np.isnan(x)]             # 篩選出是nan元素組成新一維數組, array([ 1.,  2.,  3.])

2. 篩選函數where(condition, a, b)

condition元素爲布爾值,能起到和布爾索引同樣的功能

### 篩選函數where(condition, a, b)  condition元素爲布爾值,能起到和布爾索引同樣的功能
a = np.arange(1,10,2)           # array([1, 3, 5, 7, 9])
b = np.arange(2,11,2)           # array([ 2,  4,  6,  8, 10])
f = np.array([True,True,False,True,False])
r = np.where(f, a, b)       # 如果f某位置的值爲True則取對應位置的a的值,否則取b的值
'''
array([ 1,  3,  6,  7, 10])
'''

# a/b可以不爲數組,用法如下
a = np.random.rand(12).reshape(3,4)
'''
array([[ 0.21251241,  0.28023144,  0.01282137,  0.24889945],
       [ 0.55515714,  0.95901587,  0.34933226,  0.80928682],
       [ 0.69281057,  0.63581292,  0.960359  ,  0.7399842 ]])
'''
r = np.where(a>0.5, 1, 0)
'''
array([[0, 0, 0, 0],
       [1, 1, 0, 1],
       [1, 1, 1, 1]])
'''
r2 = np.where(a>0.5, a, 0)
'''
array([[ 0.        ,  0.        ,  0.        ,  0.        ],
       [ 0.55515714,  0.95901587,  0.        ,  0.80928682],
       [ 0.69281057,  0.63581292,  0.960359  ,  0.7399842 ]])
'''

## 與r2相同結果的方法實現
a[a<=0.5] = 0           # 將a中所有小於等於0.5的都設爲0
print(a)
'''
[[ 0.          0.          0.          0.        ]
 [ 0.55515714  0.95901587  0.          0.80928682]
 [ 0.69281057  0.63581292  0.960359    0.7399842 ]]
'''

八. 數組的組裝拼接和分割

1. 拼接數組

a = np.array([[1,2],[3,4]])
b = np.array([['A','B'],['C','D']])

### 豎直拼接
v = np.vstack((a,b))
print(v)
''' 有意思的是,數字也被轉換string格式了
[['1' '2']
 ['3' '4']
 ['A' 'B']
 ['C' 'D']]
'''

### 水平拼接
h = np.hstack((a,b))
print(h)
'''
[['1' '2' 'A' 'B']
 ['3' '4' 'C' 'D']]
'''

2. 分割數組

### 分割數組
d = np.arange(32).reshape(4,8)
print(d)
'''
[[ 0  1  2  3  4  5  6  7]
 [ 8  9 10 11 12 13 14 15]
 [16 17 18 19 20 21 22 23]
 [24 25 26 27 28 29 30 31]]
'''

# 水平分割
d_split = np.hsplit(d, (3,5))      # 分割節點在第4、6兩列
for item in d_split:
    print(item)
    print("********")
''' 分割結果
[[ 0  1  2]
 [ 8  9 10]
 [16 17 18]
 [24 25 26]]
********
[[ 3  4]
 [11 12]
 [19 20]
 [27 28]]
********
[[ 5  6  7]
 [13 14 15]
 [21 22 23]
 [29 30 31]]
********
'''

# 水平分割
d_split = np.vsplit(d, 2)       # 分割節點在第3列
'''
[array([[ 0,  1,  2,  3,  4,  5,  6,  7],
        [ 8,  9, 10, 11, 12, 13, 14, 15]]),
 array([[16, 17, 18, 19, 20, 21, 22, 23],
        [24, 25, 26, 27, 28, 29, 30, 31]])]
'''

3. 查找特殊座標

### 查找特殊座標
x.nonzero()                 # 獲取x中不爲0的元素的座標,每個維度爲一行  本例:(array([0, 0, 1], dtype=int64), array([0, 1, 1], dtype=int64))
np.transpose(x.nonzero())   # 轉換爲橫縱座標對爲元素的數組,更直觀
''' 正好與x中三個不爲0的元素的橫縱座標對應
array([[0, 0],                  x[0,0] = 1
       [0, 1],                  x[0,1] = 2
       [1, 1]], dtype=int64)    x[1,1] = 3
'''

九. 數組操作符運算

1. 數組與數的計算

是將數組中的每個單元,都與此數進行運算後的結果再組成數組返回

### 數組與數的計算,是將數組中的每個單元,都與此數進行運算後的結果再組成數組返回
plus_np = one_np + 3                    # 數組內,每個元素都 + 3
print(plus_np)
'''
[[4 4]
 [4 4]
 [4 4]]
'''

mul_np = data * 2                       # 數組內,每個元素都乘以2
print(mul_np)
'''
[[ 2  4  6]
 [ 8 10 12]]
'''

2. 數組與數組的運算

數組與數組的運算,兩個數組必須有相同的形狀,對應位置的元素進行運算後的結果,再組成數組返回

### 數組與數組的運算,兩個數組必須有相同的形狀,對應位置的元素進行運算後的結果,再組成數組返回
arr = np.array([[1, 2, 3], [4, 5, 6]])      # 初始化數組
result_plus = arr + arr                 # 加法, 可以用操作符
print(result_plus)
''' 可以看到就是對應位置的元素進行了加法(1+1=2,2+2=4,3+3=6,...再將結果組成數組返回)
[[ 2  4  6]
 [ 8 10 12]]
'''

result_sub = arr - arr                  # 減法
print(result_sub)
'''
[[0 0 0]
 [0 0 0]]
'''

result_multi = arr * arr                # 乘法
print(result_multi)
'''
[[ 1  4  9]
 [16 25 36]]
'''

result_div = arr / arr                  # 除法
print(result_div)
''' python3中,除法運算符"/"得到的是小數
[[ 1.  1.  1.]
 [ 1.  1.  1.]]
'''

result_div += result_multi              # 可以使用+=  *=等賦值符號給原數組設值,但要注意數據類型和精度損失問題,有時候因爲數據類型不能轉換而報錯
print(result_div)
''' 
[[  2.   5.  10.]
 [ 17.  26.  37.]]
'''

完全不同形狀的數組,不允許基本運算

### 完全不同形狀的數組,不允許基本運算
arr + plus_np           # 報錯: operands could not be broadcast together with shapes (2,3) (3,2)

3. 擴充轉換

擴充轉換,當數組之間在某一維度有相同的形狀時,可以進行擴充轉換,再進行加減乘除等算法

### 擴充轉換,當數組之間在某一維度有相同的形狀時,可以進行擴充轉換,再進行加減乘除等算法
a = np.array([[1,1,1],[2,2,2],[3,3,3],[4,4,4]])
b = np.array([0,1,2])

a + b               #可以發現 雖然兩個數組維度不一樣,但是可以相加 因爲b被縱向擴充到了(3,4)的形狀
''' 第一行爲[1,1,1] + [0,1,2], 第二行爲[2,2,2] + [0,1,2] ...
array([[1, 2, 3],
       [2, 3, 4],
       [3, 4, 5],
       [4, 5, 6]])
'''

c = [[0],
     [1],
     [2],
     [3]]
a + c               # c縱向填充爲(3,4)的形狀
'''
array([[1, 1, 1],
       [3, 3, 3],
       [5, 5, 5],
       [7, 7, 7]])
'''

可以用擴充轉換,來轉換必要格式的數組

### 可以用擴充轉換,來轉換必要格式的數組
m = np.array([1,2,3,4])
n = np.zeros((3,4))
rr = m + n          # 轉換
''' 轉換爲(3*4)的格式
array([[ 1.,  2.,  3.,  4.],
       [ 1.,  2.,  3.,  4.],
       [ 1.,  2.,  3.,  4.]])
'''

十. 數組的函數運算

  1. 基本數學函數運算
  • add() subtract() multiply() divide() mod() 對應兩個數組的加減乘除和取模
  • absolute() fabs() 數組元素的絕對值
  • power() 第一個數組元素爲底,第二個數組元素爲指數進行冪運算
  • exp() exp2() 以e或2爲底的指數結果
  • log() log2() log10() 以e、2、10爲底的對數
  • sqrt() square() 平方根 平方
  • sin() cos() tan() 正弦、餘弦、正切
  • arcsin() arccos() arctan() 反正弦、反餘弦、反正切
  • greater(x1,x2) greater_equal(x1,x2) 比較,如果x1>x2 (x1>=x2) 則返回True 同理有less() less_equal() equal() not_equal()
  • floor() ceil() trunc() 向下取整、向上取整、截掉小數點
"""數組的函數運算"""
### 基本數學函數運算
a = np.arange(4)                # array([0, 1, 2, 3])
b = np.arange(4,8)              # array([4, 5, 6, 7])
np.add(a, b)                    # array([ 4,  6,  8, 10])
np.exp(a)                       # 對每個元素i求e^i(e是自然常數)組成新的數組 array([  1.        ,   2.71828183,   7.3890561 ,  20.08553692])

'''
add()  subtract()  multiply()  divide()  mod() 對應兩個數組的加減乘除和取模
absolute() fabs() 數組元素的絕對值
power() 第一個數組元素爲底,第二個數組元素爲指數進行冪運算
exp()   exp2() 以e或2爲底的指數結果
log()  log2()  log10()   以e、2、10爲底的對數
sqrt()   square()   平方根  平方
sin()  cos()  tan()  正弦、餘弦、正切
arcsin() arccos() arctan() 反正弦、反餘弦、反正切
greater(x1,x2) greater_equal(x1,x2)  比較,如果x1>x2 (x1>=x2) 則返回True  同理有less()  less_equal()  equal() not_equal()
floor() ceil()  trunc()  向下取整、向上取整、截掉小數點
'''

2. 統計函數

  • max() 最大
  • min() 最小
  • std() 標準差
  • var() 方差
  • argmin() argmax() 最小、最大值索引(平鋪成一維的索引)
  • cumsum() 累加和
### 統計函數
a = np.arange(12).reshape(3,4)
print(a)
'''
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
'''

a.sum()             # 全部求和,本例:66
a.sum(axis=0)       # 縱向求和 array([12, 15, 18, 21])
a.sum(axis=1)       # 橫向求和 array([ 6, 22, 38])

a.min()             # 最小值
a.min(axis=0)       # array([0, 1, 2, 3])
a.min(axis=1)       # array([0, 4, 8])

# 累加和
a.cumsum()          # array([ 0,  1,  3,  6, 10, 15, 21, 28, 36, 45, 55, 66], dtype=int32)
a.cumsum(axis=0)    # 縱向累加和
'''
array([[ 0,  1,  2,  3],
       [ 4,  6,  8, 10],
       [12, 15, 18, 21]], dtype=int32)
'''

a.cumsum(axis=1)    # 橫向累加和
'''
array([[ 0,  1,  3,  6],
       [ 4,  9, 15, 22],
       [ 8, 17, 27, 38]], dtype=int32)
'''

'''
max()   最大
min()   最小
std()   標準差
var()   方差
argmin()  argmax()  最小、最大值索引(平鋪成一維的索引)
cumsum() 累加和
'''

3. 排序

### 排序
a = np.random.rand(5)           # array([ 0.28450601,  0.39208123,  0.76706749,  0.0585455 ,  0.21775495])
b = np.sort(a)                  # array([ 0.0585455 ,  0.21775495,  0.28450601,  0.39208123,  0.76706749])

a = np.random.randn(12).reshape(3, 4)
print(a)
'''
[[-1.01289904 -0.93940421  0.29553346  1.68095943]
 [ 0.61732077 -1.32744617  0.00564842 -0.38529139]
 [ 0.43369961 -1.39254848 -0.99564321 -0.06965223]]
'''

np.sort(a, axis=0)              # 每列排序,從小到大,每行數據都被打亂了
'''
array([[-1.01289904, -1.39254848, -0.99564321, -0.38529139],
       [ 0.43369961, -1.32744617,  0.00564842, -0.06965223],
       [ 0.61732077, -0.93940421,  0.29553346,  1.68095943]])
'''

數組排序np.sort()也可以對一些特殊格式的元素數據進行排序,不過需要定義好dtype與order入參

### 使用關鍵字段進行排序
b_dtype=[('姓名','U10'),('語文',int),('數學',int),('平均',float)]           # 定義符合數據格式的dtype,這裏起的名字在排序時有用
b_data = [('小明', 75, 78, 0), ('小紅', 90, 88, 0), ('小王', 47, 98, 0)]      # 定義數據
b = np.array(b_data, dtype=b_dtype)         # 創建數組
b.shape         # 注意這裏的形狀是(3,),是一維數組
'''
array([('小明', 75, 78,  0.), ('小紅', 90, 88,  0.), ('小王', 47, 98,  0.)],
      dtype=[('姓名', '<U10'), ('語文', '<i4'), ('數學', '<i4'), ('平均', '<f8')])
'''

np.sort(b, order=['語文'])     # 按'語文'關鍵字排序
'''
array([('小王', 47, 98,  0.), ('小明', 75, 78,  0.), ('小紅', 90, 88,  0.)],
      dtype=[('姓名', '<U10'), ('語文', '<i4'), ('數學', '<i4'), ('平均', '<f8')])
'''

4. 查找插入索引

###查找 searchsorted(array, num) array只能是一維數組
a = np.sort(np.random.randint(1,30,10))     # 生成一組有序排列的數組 array([ 2,  3,  4, 10, 11, 12, 16, 22, 23, 29])
np.searchsorted(a, 4)                       # 查看元素4可以插入a的位置,本例:2
np.searchsorted(a, 4, side='right')         # 默認site='left' 在左方插入,設置爲right,右方插入,如果有與插入相等的元素,則放在最右邊,本例:3
np.searchsorted(a, 15)                      # 查看元素15可以插入a的位置,本例:6
np.searchsorted(a, [3,4,12,20])             # 查看列表每個元素可以插入的位置list  array([1, 2, 5, 7], dtype=int64)

5. 提取滿足條件的元素

### 提取元素
arr = np.arange(12).reshape(3,4)
condition = np.mod(arr, 6) != 0

np.extract(condition, arr)      # 提取爲True的元素  array([ 1,  2,  3,  4,  5,  7,  8,  9, 10, 11]),捨棄了能被6整除的0,6
arr[np.mod(arr, 6) != 0]        # 使用布爾篩選,與上面的結果相同   array([ 1,  2,  3,  4,  5,  7,  8,  9, 10, 11])

十一. 線性代數運算

1. np.dot(a,b) 矩陣乘法運算

### 矩陣乘法運算  np.dot(a,b)
a = np.arange(12).reshape(3,4)
print(a)
'''
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
'''

b = np.arange(12).reshape(4,3)
print(b)
'''
[[ 0  1  2]
 [ 3  4  5]
 [ 6  7  8]
 [ 9 10 11]]
'''

np.dot(a,b)             # 矩陣乘法
'''
array([[ 42,  48,  54],
       [114, 136, 158],
       [186, 224, 262]])
'''

2. np.linalg.inv(a) 逆矩陣

### 逆矩陣
a = np.arange(1,10).reshape(3,3)
np.linalg.inv(a)
'''
array([[  3.15251974e+15,  -6.30503948e+15,   3.15251974e+15],
       [ -6.30503948e+15,   1.26100790e+16,  -6.30503948e+15],
       [  3.15251974e+15,  -6.30503948e+15,   3.15251974e+15]])
'''

3. np.linalg.solve() 求解方程組

### 求解方程組
# 3x1 + 4x2 = 4
# 2x1 + 6x2 = 3
a_np = np.array([[3, 4],[2, 6]])
r_np = np.array([4, 3])

np.linalg.solve(a_np, r_np)
''' 求得結果如下,可驗證: 3*1.2+4*0.1=4    2*1.2+6*0.1=3
array([ 1.2,  0.1])
'''

4. LA.eig() 特徵值、特徵向量

### 特徵值、特徵向量  LA.eig()
from numpy import linalg as LA
q = np.diag([1,2,3,4])          # 創建矩陣
print(q)
'''
[[1 0 0 0]
 [0 2 0 0]
 [0 0 3 0]
 [0 0 0 4]]
'''
x, y = LA.eig(q)        # 求解特徵值、特徵向量
print(x)                # [ 1.  2.  3.  4.]
print(y)
'''
[[ 1.  0.  0.  0.]
 [ 0.  1.  0.  0.]
 [ 0.  0.  1.  0.]
 [ 0.  0.  0.  1.]]
'''

5. np.mgrid 快速創建特定數據和格式的多維網格

### 快速創建特定數據和格式的多維網格
a = np.mgrid[1:6:1]         # 一維 array([1, 2, 3, 4, 5])

part_1, part_2 = np.mgrid[1:3:1,6:9:1]
print(part_1)
''' 分兩部分,每個部分的shape都是(3-1,9-6)=(2,3),第一個部分縱向填充1,2,第二部部分橫向填充6,7,8
[[1 1 1]
 [2 2 2]]
'''
print(part_2)
'''
[[6 7 8]
 [6 7 8]]
'''

b = np.mgrid[1:3:1,6:9:1]       # 也可以總返回
print(b)
'''
[[[1 1 1]
  [2 2 2]]
 [[6 7 8]
  [6 7 8]]]
'''

# 可以利用這些數據再進行計算分析,或者自造數據
(np.cos(part_1) + np.sqrt(part_2))* np.log(part_2)
'''
array([[ 5.35698821,  6.19977407,  7.00507592],
       [ 3.64326141,  4.33860998,  5.01619584]])
'''

6. np.meshgrid 網格數據及拼裝二維座標

## meshgrid 是另一種橫縱比網格數據
nx,ny = (3,2)
#從0開始到1結束,返回一個numpy數組,nx代表數組中元素的個數
x = np.linspace(0,1,nx)
#[ 0.   0.5  1. ]
y = np.linspace(0,1,ny)
# [0.  1.]
xv,yv = np.meshgrid(x,y)
'''
xv
[[ 0.   0.5  1. ]
 [ 0.   0.5  1. ]]
 yv
 [[ 0.  0.  0.]
  [ 1.  1.  1.]]
'''

# 這種數據非常適合拼裝平面座標系
np.c_[xv.ravel(), yv.ravel()].reshape(xv.shape[0], xv.shape[1], -1)
'''array([[[ 0. ,  0. ],
        [ 0.5,  0. ],
        [ 1. ,  0. ]],
       [[ 0. ,  1. ],
        [ 0.5,  1. ],
        [ 1. ,  1. ]]])
'''

十二. 儲存數組數據到文件與讀取操作

"""儲存數組數據到文件與讀取操作"""
### 儲存爲二進制文件,拓展名爲.npy、.npz
np.save('.temp_array',a)    # 儲存
b = np.load('.temp_array.npy')      # 讀取
'''
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
'''

## 非壓縮存儲
a = np.arange(1,10,2)           # array([1, 3, 5, 7, 9])
b = np.arange(2,11,2)           # array([ 2,  4,  6,  8, 10])
np.savez('.temp_array_z',arg1=a, arg2=b)        # 儲存後綴名爲.npz

z_load = np.load('.temp_array_z.npz')       # 讀文件
z_load['arg1']                              # 讀數據
'''
array([1, 3, 5, 7, 9])
'''

### 儲存爲文本文件
np.savetxt('out.txt', a, delimiter=',', fmt='%d')       # 以','分隔,數據格式類似csv文件
txt_load = np.loadtxt('out.txt', delimiter=',')

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章