1. 程式人生 > >【Python】Numpy簡單入門

【Python】Numpy簡單入門

Numpy
  Numpy是Python中科學計算的核心庫。Numpy提供了高效能的多維陣列物件,還有用於處理這些陣列的工具。
陣列
  Numpy的主要資料型別是ndarray即多維陣列,可以用巢狀的Python列表中初始化numpy陣列,並使用方括號訪問元素。陣列具有以下幾個屬性:

  • ndarray.ndim: 陣列的維數
  • ndarray.shape: 陣列每一維的大小
  • ndarray.size: 陣列中全部元素的數量
  • ndarray.dtype: 陣列中元素的型別(numpy.int32, numpy.int16, and numpy.float64等)
  • ndarray.itemsize:每個元素佔幾個位元組
    陣列操作
import numpy as np                # 匯入numpy模組
a = np.array([1,2,3])
print(type(a))                            # a的型別是numpy.ndarray
print(a.shape)                           # 一維陣列,列向量
print(a[0],a[1],a[2])                    # 下標從0開始計數
a[0] = 5                                      # 修改陣列元素的值
print(a)
b = np.array([[1,2,3],[4,5,6]])      
print(b.shape)                          # 二維陣列,2×3
print(b[0,0],b[0,1],b[1,0])          # 二維陣列下標

c = np.array([1,])                   # 一維陣列
print(c.shape)

執行結果

<class 'numpy.ndarray'>
(3,)

1 2 3

[5 2 3]

(2, 3)

1 2 4

(1,)

建立陣列

import numpy as np
a = np.zeros((2,2))                  # 2×2全零陣列
print(a)
b = np.ones((1,2))                   # 2×2全一陣列
print(b)
c = np.full((2,2),7)                 # 2×2常量陣列,執行結果是‘7’而不是‘7.’
print(c)
d = np.eye(2)                        # 2×2單位陣列
print(d)
e = np.random.random((2,2))          # 2×2隨機陣列,範圍為[0,1]
print(e)

執行結果

[[ 0.  0.]
 [ 0.  0.]]

[[ 1.  1.]]

[[7 7]
 [7 7]]

[[ 1.  0.]
 [ 0.  1.]]

[[ 0.75674195  0.00198805]
 [ 0.0375324   0.72334415]]

陣列索引
  Numpy提供了幾種索引陣列的方法。
切片
  類似於Python中的列表List,可以將numpy陣列進行切片。如果是多維陣列,需要為陣列的每個維度指定一個切片。

import numpy as np
a = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])
b = a[:2,1:3]

print(a)
print(b)
print(a[0,1])                        # 第一行第二個 
b[0,0] = 77                          # a、b共用同一資料
print(a[0,1])

a[0,1] = 60                          # 改變a或b,都會改動另一方,類似C++中引用
print(b[0,0])

執行結果

[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]

[[2 3]
 [6 7]]

2

77

60

整型索引與切片索引混合
  這個做法會產生比原始陣列更低階的陣列。

import numpy as np
a = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])
row_r1 = a[1,:]                      # 產生一維陣列     
row_r2 = a[1:2,:]                    # 產生二維陣列
print(row_r1,row_r1.shape)
print(row_r2,row_r2.shape)

col_r1 = a[:,1]
col_r2 = a[:,1:2]
print(col_r1,col_r1.shape)
print(col_r2,col_r2.shape)

執行結果

[5 6 7 8] (4,)

[[5 6 7 8]] (1, 4)

[ 2  6 10] (3,)

[[ 2]
 [ 6]
 [10]] (3, 1)

整數陣列索引
  當對numpy陣列使用切片索引時,生成的陣列將始終是原始陣列的子陣列。而整數陣列索引則允許使用另一個數組的資料構造任意的陣列。

import numpy as np
a = np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]])
print(a[[0,1,2],[0,1,0]])                      # 行、列
print(np.array([a[0,0],a[1,1],a[2,0]]))        # 每個的座標

b = np.array([0,2,0,1])
print(a[np.arange(4),b])

a[np.arange(4),b] += 10  
print(a)    

執行結果

[1 5 7]

[1 5 7]

[ 1  6  7 11]

[[11  2  3]
 [ 4  5 16]
 [17  8  9]
 [10 21 12]]

布林陣列索引
  布林陣列索引可挑選出一個數組的任意元素。通常,這種型別的索引用於選擇滿足某些條件的陣列的元素。

 import numpy as np
a = np.array([[1,2],[3,4],[5,6]])              
bool_idx = (a > 2)                             # 逐個比較  
print(bool_idx)
print(a[bool_idx])
print(a[a > 2])

執行結果

[[False False]
 [ True  True]
 [ True  True]]

[3 4 5 6]

[3 4 5 6]

資料型別

import numpy as np
x = np.array([1,2])                            # int64
print(x,x.dtype)

x = np.array([1.0,2.0])                        # float64
print(x,x.dtype)

x = np.array([1.5,2.8],dtype = np.int64)       # 強制轉換,int64
print(x,x.dtype)

執行結果

[1 2] int32

[ 1.  2.] float64

[1 2] int64

陣列計算
  陣列可以進行基本的數學函式計算,並且可以作為操作符過載和在numpy模組中的函式。

import numpy as np
x = np.array([[1,2],[3,4]],dtype = np.float64)
y = np.array([[5,6],[7,8]],dtype = np.float64)

print(x + y)                             # 加法
print(np.add(x,y))

print(x - y)                             # 減法
print(np.subtract(x,y))

print(x * y)                             # 乘法
print(np.multiply(x,y))

print(x / y)                             # 除法
print(np.divide(x,y))

print(np.sqrt(x))                         # 開方
print(np.sum(x))                          # 所有元素相加
print(np.sum(x,axis = 0))                 # 列向量相加
print(np.sum(x,axis = 1))                 # 行向量相加

v = np.array([9,10])
w = np.array([11,12])

print(x.T)                                # 多維陣列轉置
print(v.T)                                # 一維陣列轉置不發生改變

print(v.dot(w))                           # 計算內積
print(np.dot(v,w))
print(np.dot(x,v))
print(np.dot(x,y))

執行結果

[[  6.   8.]                              # 加法 
 [ 10.  12.]]
[[  6.   8.]
 [ 10.  12.]]

[[-4. -4.]                                # 減法
 [-4. -4.]]
[[-4. -4.]
 [-4. -4.]]

[[  5.  12.]                              # 乘法
 [ 21.  32.]]
[[  5.  12.]
 [ 21.  32.]]

[[ 0.2         0.33333333]                # 除法
 [ 0.42857143  0.5       ]]
[[ 0.2         0.33333333]
 [ 0.42857143  0.5       ]]

[[ 1.          1.41421356]                # 開方
 [ 1.73205081  2.        ]]

10.0                                      # 所有元素相加

[ 4.  6.]                                 # 列向量相加

[ 3.  7.]                                 # 行向量相加

[[ 1.  3.]                                # 多維陣列轉置
 [ 2.  4.]]

[ 9 10]                                   # 一維陣列轉置不發生改變

219                                       # 計算內積v.dot(w)

219                                       # 計算內積np.dot(v,w)

[ 29.  67.]                               # 計算內積np.dot(x,v)

[[ 19.  22.]                              # 計算內積np.dot(x,y)
 [ 43.  50.]]

Broadcasting
  Broadcasting廣播機制是Python中一種強大的機制,它允許numpy在執行算術運算時使用不同形狀的陣列。當對一個較小的陣列和一個較大的陣列進行運算時,通過多次使用較小的陣列來對較大的陣列執行一些操作。

  import numpy as np
x = np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]])
v = np.array([1,0,1])

y_empty = np.empty_like(x)                     # 建立一個與x大小相同的空矩陣
for i in range(4):
    y_empty[i,:] = x[i,:] + v;
print(y_empty)

vv = np.tile(v,(4,1))               # 將v垂直地堆疊起來,形成新陣列vv,比上一種方法執行速度快
print(vv)
y_tile = x + vv
print(y_tile)

y_bc = x + v                                   # 傳播機制BoardCasting
print(y_bc)

執行結果

[[ 2  2  4]                                   # y_empty
 [ 5  5  7]
 [ 8  8 10]
 [11 11 13]]

[[1 0 1]                                      # vv
 [1 0 1]
 [1 0 1]
 [1 0 1]]

[[ 2  2  4]                                   # y_tile
 [ 5  5  7]
 [ 8  8 10]
 [11 11 13]]

[[ 2  2  4]                                   # y_bc
 [ 5  5  7]
 [ 8  8 10]
 [11 11 13]]