Python 3.6 NumPy一
阿新 • • 發佈:2019-02-12
Python下有很多科學計算庫,這一個支點我開始學習NumPy,然後做做筆記
1、安裝numpy,沒花頭,pip install numpy,linux記得sudo
先來對比一下效率,兩個函式,一個通過python的list去做,一個通過numpy庫去做,看一下計算的時間
import numpy as np from datetime import datetime def python_style(n: int): l1 = [x ** 2 for x in range(n)] l2 = [y ** 3 for y in range(n)] ret = [] for item in range(len(l1)): ret.append(l1[item] + l2[item]) return ret def numpy_style(n: int): a = np.arange(n) ** 2 b = np.arange(n) ** 3 return a + b start = datetime.now() py_arr = python_style(1000) print(datetime.now() - start) start = datetime.now() numpy_arr = numpy_style(1000) print(datetime.now() - start)
0:00:00.001608 ----python
0:00:00.000050 ----numpy
可以發現,巨大的差距,接下來是基礎掃盲的過程。。。。。
# 建立一個numpy.ndarray型別的物件,他是一個數組 np_arr1 = np.array([[1, 2, 3], [2, 3, 4], [3, 4, 5]]) print(np_arr1) # 看下物件的內容 # [[1 2 3] # [2 3 4] # [3 4 5]] print(type(np_arr1)) # 物件型別 # <class 'numpy.ndarray'> print(np_arr1.dtype) # 中間每一個元素的型別 # int64 print(np_arr1.itemsize) # 每個元素的大小,裡面每個元素都是int64,也就是8個位元組 # 8 print(np_arr1.ndim) # 維度個數 # 2 print(np_arr1.shape) # 每個維度的元素個數 # (3, 3) print(np_arr1.size) # 總元素個數,等於shape列出維度的乘積 # 9 print(np_arr1[1]) # 注意這裡的[]不代表一個list而是一個numpy.ndarray容器 # [2 3 4] print(type(np_arr1[1])) # 這個陣列試一個ndarray層層疊加的過程 # <class 'numpy.ndarray'>
再來看一下簡單的方法
# sharp是一個模型,確定好模型以後就可以通過模型構建陣列 # def zeros(shape, dtype=None, order='C') array = np.zeros((3, 5)) print(array) # [[ 0. 0. 0. 0. 0.] # [ 0. 0. 0. 0. 0.] # [ 0. 0. 0. 0. 0.]] print(array.dtype) # 注意元素型別,float會有一個點'.'跟在數字後面 # float64 # 同樣的還有一個 array = np.ones((3, 5)) print(array) # [[ 1. 1. 1. 1. 1.] # [ 1. 1. 1. 1. 1.] # [ 1. 1. 1. 1. 1.]] # 還有一個np.empty((3,5))這個就是建立一個模型,並不初始化,裡面會有很多野資料 # arange()和range效果差不多 array = np.arange(15) print(array) # [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14] # 多維陣列也能這麼建立 # array = np.array([np.arange(5), np.arange(5), np.arange(5)]) # [[0 1 2 3 4] # [0 1 2 3 4] # [0 1 2 3 4]] # 通過reshape去修改重構 array = np.reshape(array, [3, 5]) print(array) # [[ 0 1 2 3 4] # [ 5 6 7 8 9] # [10 11 12 13 14]] # 同樣還可以扁平化 array = np.ravel(array) print(array) # [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14] # N*N單位矩陣(eye,會有一個條對角線全為1 array = np.eye(5,5) # 第一個引數行數,第二個引數列數 print(array) # [[ 1. 0. 0. 0. 0.] # [ 0. 1. 0. 0. 0.] # [ 0. 0. 1. 0. 0.] # [ 0. 0. 0. 1. 0.] # [ 0. 0. 0. 0. 1.]] array = np.identity(4) # 與上面類似,只不過是個正方形 print(array) # [[ 1. 0. 0. 0.] # [ 0. 1. 0. 0.] # [ 0. 0. 1. 0.] # [ 0. 0. 0. 1.]]
陣列的取值
# 以前的多維陣列,我都是通過不斷疊加下標去取值的,numpy就不一樣了(當然你一定要這麼寫也是可以的)
array = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(array)
# [[1 2 3]
# [4 5 6]
# [7 8 9]]
print(array[0, 1]) # 2
print(array[2, 0]) # 7
# [x,y] x代表第一個維度的第幾個元素, y代表x所在維度的第幾個元素
# 試一下三維
array = np.array(
[
[
[1.1, 1.2, 1.2], [2.1, 2.2, 2.3], [3.1, 3.2, 3.3]
],
[
[4.1, 4.2, 4.3], [5.1, 5.2, 5.3], [6.1, 6.2, 6.3]
],
[
[7.1, 7.2, 7.3], [8.1, 8.2, 8.3], [9.1, 9.2, 9.3]
]
])
print(array)
# [[[ 1.1 1.2 1.2]
# [ 2.1 2.2 2.3]
# [ 3.1 3.2 3.3]]
#
# [[ 4.1 4.2 4.3]
# [ 5.1 5.2 5.3]
# [ 6.1 6.2 6.3]]
#
# [[ 7.1 7.2 7.3]
# [ 8.1 8.2 8.3]
# [ 9.1 9.2 9.3]]]
print(array[0, 1, 0]) # 2.1
print(array[2, 2, 2]) # 9.3
型別轉換
# 轉換資料型別
# int -> float
int_array = np.arange(5)
print(int_array)
# [0 1 2 3 4]
print(int_array.dtype)
# int64
float_array = int_array.astype(np.float64) # 轉換
print(float_array)
# [ 0. 1. 2. 3. 4.]
print(float_array.dtype)
# float64
# float -> int
float_array = np.arange(0, 4, 0.5)
print(float_array)
# [ 0. 0.5 1. 1.5 2. 2.5 3. 3.5]
print(float_array.astype(np.int64))
# [0 0 1 1 2 2 3 3]
# 自定義型別
# 先看一下基礎型別
t = np.dtype(np.int64)
print(t.type)
print(t.char)
print(t.str)
# <class 'numpy.int64'>
# l
# <i8
# 之後在dtype引數那裡就可以填入l或者<i8或者np.int64代表元素型別
# 先定義個自定義的符合型別,這裡的第一個型別‘name’後面跟著兩個引數,是因為字串需要確認長度
custom_type = np.dtype([('name', np.str_, 40), ('itemnum', np.int64), ('price', np.float64)])
print(custom_type)
# [('name', '<U40'), ('itemnum', '<i8'), ('price', '<f8')]
array = np.array([
('TV',20,19.9),
('PC', 5, 99.9)
], dtype=custom_type)
print(array)
# [('TV', 20, 19.9) ('PC', 5, 99.9)]
print(array['name'])
# ['TV' 'PC']
# 陣列運算
array = np.array([
[1, 2, 3],
[4, 5, 6]
])
print(array)
# [[1 2 3]
# [4 5 6]]
print(array - array)
# [[0 0 0]
# [0 0 0]]
print(array * array)
# [[ 1 4 9]
# [16 25 36]]
print(array ** 2)
# [[ 1 4 9]
# [16 25 36]]
print(1 / array)
# [[ 1. 0.5 0.33333333]
# [ 0.25 0.2 0.16666667]]
print(array // 2)
# [[0 1 1]
# [2 2 3]]
# 切片
array = np.array(
[
[
[1, 2],
[3, 4]
],
[
[5, 6],
[7, 8]
],
[
[9, 10],
[11, 12]
]
]
)
# 這是一個三維陣列,那切片其實是一樣的,就是需要理一下思路
print(array[:]) # 遍歷三維陣列內所有的二維陣列
print('-------------------')
print(array[0:2]) # 遍歷三維陣列內前兩個二維陣列
print('-------------------')
print(array[-2:]) # 遍歷三維陣列內後兩個二維陣列
print('-------------------')
print(array[::-1]) # 將陣列內該維度的元素反向排序,重新生成一個
# 再進一層
# 遍歷三維陣列的倒數兩個元素,會得到兩個二維陣列
# 然後遍歷這兩個二維陣列的第二個元素
print('-------------------')
print(array[-2:, 1:])
# [[[ 7 8]]
#
# [[11 12]]]
# 這個時候,再去拿那兩個二維陣列的第一個值
print('-------------------')
print(array[-2:, 1:, 0])
# [[ 7]
# [11]]
# 這個時候要看一下,他返回的是什麼
ret_arr = array[-2:, 1:, 0]
# 他返回一個二維陣列,二維陣列的每一個元素都是一個只有一個元素的以為陣列
print('-------------------')
print(ret_arr[1, 0]) # 11
# 每一個逗號都代表了一層維度,通過維度可以返回多個值或者一個值,返回的型別需要注意
# 測試一下取單一值的返回型別
print('-------------------')
print(array[0, 0, 0]) # 1
print(type(array[0, 0, 0])) # int64
print(array[0, ...]) # 只需要第一個維度的第0個元素
print(array[...,1] # 需要最後一個維度所有元素的第二個元素
names = np.array(['aa', 'bb', 'cc', 'dd', 'aa', 'bb', 'cc'])
data = np.random.randn(7, 4)
print(data)
# [[-0.7730927 -0.61826381 0.5954012 0.83927967]
# [ 0.17513281 -0.02061551 -0.06197476 0.87479289]
# [-0.21595191 0.15207614 -1.68710421 -2.069167 ]
# [ 0.37064103 0.50932026 0.210167 1.56221687]
# [ 0.41340528 1.445154 -1.24314649 -1.06785139]
# [ 1.43764089 1.0660907 -0.3816355 -2.27248331]
# [-0.17388653 0.14872601 -1.23795655 -0.04884237]]
print('---------------------------------------------------')
print(names == 'aa')
# [ True False False False True False False]
print(data[names == 'aa'])
# [[-0.7730927 -0.61826381 0.5954012 0.83927967]
# [ 0.41340528 1.445154 -1.24314649 -1.06785139]]
# 這個挺神奇的,將兩個陣列進行匹配,效果自己看一下吧
# names == 'aa' # 等於
# names != 'aa' # 不等於
# (names == 'aa') == -(names != 'aa') # 這兩個是等價的
data = np.arange(7)
print(data) # [0 1 2 3 4 5 6]
print(data[(names == 'aa') | (names == 'bb')]) # [0 1 4 5]
# 接下來我們把data裡所有小於4的元素賦值為666
data[data < 4] = 666
print(data) # [666 666 666 666 4 5 6]
# 花式索引
# 根據給定陣列選取目標陣列的元素
data = np.empty((10, 5), dtype=np.int64)
for i in range(10):
data[i] = i
print(data)
# [[0 0 0 0 0]
# [1 1 1 1 1]
# [2 2 2 2 2]
# [3 3 3 3 3]
# [4 4 4 4 4]
# [5 5 5 5 5]
# [6 6 6 6 6]
# [7 7 7 7 7]
# [8 8 8 8 8]
# [9 9 9 9 9]]
print(data[[1, 3, 4, 7, 9]])
# [[1 1 1 1 1]
# [3 3 3 3 3]
# [4 4 4 4 4]
# [7 7 7 7 7]
# [9 9 9 9 9]]
data = np.arange(32).reshape(8, 4)
print(data)
# [[ 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]]
print('--------------------------')
print(data[[1, 3, 2, 4], [0, 3, 2, 1]])
# [ 4 15 10 17] 兩個陣列內的元素一一對應,選取第一個維度下標為1的第0個元素。。。。。。。
print('--------------------------')
print(data[[1, 5, 7, 2]])
# [[ 4 5 6 7]
# [20 21 22 23]
# [28 29 30 31]
# [ 8 9 10 11]]
print(data[[1, 5, 7, 2]][:, [3, 2, 1]]) # 這裡其實是兩步
# [[ 7 6 5]
# [23 22 21]
# [31 30 29]
# [11 10 9]]
print('--------------------------')
print(data[np.ix_([0, 1], [0, 3])])
# 1.選取第一個維度第0個元素的第0個元素和第3個元素
# 2.選取第一個維度第1個元素的第0個元素和第3個元素
# [[0 3]
# [4 7]]
# 陣列轉置
arr = np.arange(15)
arr.reshape(3, 5)
print(arr)
# [[ 0 1 2 3 4]
# [ 5 6 7 8 9]
# [10 11 12 13 14]]
print(arr.T)
# [[ 0 5 10]
# [ 1 6 11]
# [ 2 7 12]
# [ 3 8 13]
# [ 4 9 14]]
arr.shape = (3, 5) # 也可以這樣直接轉
print(arr)
# [[ 0 1 2 3 4]
# [ 5 6 7 8 9]
# [10 11 12 13 14]]
print(arr.transpose()) # 這個也是轉置
# [[ 0 5 10]
# [ 1 6 11]
# [ 2 7 12]
# [ 3 8 13]
# [ 4 9 14]]
print(arr)
# [[ 0 1 2 3 4]
# [ 5 6 7 8 9]
# [10 11 12 13 14]]
arr.resize(5,3) # 之前幾個函式有的試通過返回值重新構建了一個數組,這個函式是直接改的
print(arr)
# [[ 0 1 2]
# [ 3 4 5]
# [ 6 7 8]
# [ 9 10 11]
# [12 13 14]]
其實我還有一段,先休息一下
# 陣列的混合組合
data = np.arange(9).reshape(3, 3)
data2 = data * 2
print(data)
# [[0 1 2]
# [3 4 5]
# [6 7 8]]
print(data2)
# [[ 0 2 4]
# [ 6 8 10]
# [12 14 16]]
# 水平組合
print(np.hstack((data, data2)))
# [[ 0 1 2 0 2 4]
# [ 3 4 5 6 8 10]
# [ 6 7 8 12 14 16]]
# 垂直組合
print(np.vstack((data, data2)))
# [[ 0 1 2]
# [ 3 4 5]
# [ 6 7 8]
# [ 0 2 4]
# [ 6 8 10]
# [12 14 16]]
# 當axis=0的時候是垂直組合,axis=1的時候是水平組合
print(np.concatenate((data, data2), axis=0))
# [[ 0 1 2]
# [ 3 4 5]
# [ 6 7 8]
# [ 0 2 4]
# [ 6 8 10]
# [12 14 16]]
print(np.concatenate((data, data2), axis=1))
# [[ 0 1 2 0 2 4]
# [ 3 4 5 6 8 10]
# [ 6 7 8 12 14 16]]
# 深度組合
# 第一個陣列的第一個元素和第二個陣列的第一個元素,組成一個數組,以此類推
print(np.dstack((data, data2)))
# [[[ 0 0]
# [ 1 2]
# [ 2 4]]
#
# [[ 3 6]
# [ 4 8]
# [ 5 10]]
#
# [[ 6 12]
# [ 7 14]
# [ 8 16]]]
print('------------------------------')
data = np.arange(2)
data2 = data * 2
print(data)
# [0 1]
print(data2)
# [0 2]
print(np.column_stack((data, data2)))
# [[0 0]
# [1 2]]
print(np.dstack((data, data2)))
# [[[0 0]
# [1 2]]]
# colum_stack == dstack
print('---------------------------------')
print(np.row_stack((data, data2)))
# [[0 1]
# [0 2]]
print(np.vstack((data, data2)))
# [[0 1]
# [0 2]]
# row_stack == vstack
print('----------------------------------')
# 陣列的分割
data = np.arange(1, 10).reshape(3, 3)
print(data)
# [[1 2 3]
# [4 5 6]
# [7 8 9]]
d1, d2, d3 = np.hsplit(data, 3)
print(d1)
# [[1]
# [4]
# [7]] ==> [[1] [4] [7]]
print(d2)
# [[2]
# [5]
# [8]]
print(d3)
# [[3]
# [6]
# [9]]
d1, d2, d3 = np.vsplit(data, 3)
print(d1)
# [[1 2 3]]
print(d2)
# [[4 5 6]]
print(d3)
# [[7 8 9]]
# np.split(data,3,0) == np.vsplit(data,3)
# np.split(data,3,1) == np.hsplit(data,3)
print('-----------------------------')
data = np.arange(27).reshape(3, 3, 3)
print(data)
# [[[ 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]]]
d1, d2, d3 = np.dsplit(data, 3)
print(d1)
# [
# [
# [ 0]
# [ 3]
# [ 6]
# ]
#
# [
# [ 9]
# [12]
# [15]
# ]
#
# [
# [18]
# [21]
# [24]
# ]
# ]
# 通用函式
array = np.arange(9, dtype=np.int64).reshape(3, 3)
print(array)
# [[0 1 2]
# [3 4 5]
# [6 7 8]]
# 平方
s_arr = np.square(array)
print(s_arr)
# [[ 0 1 4]
# [ 9 16 25]
# [36 49 64]]
# 平方根
print(np.sqrt(s_arr))
# [[ 0. 1. 2.]
# [ 3. 4. 5.]
# [ 6. 7. 8.]]
# e=2.718281 e的x次方
print(np.exp(array))
# [[ 1.00000000e+00 2.71828183e+00 7.38905610e+00]
# [ 2.00855369e+01 5.45981500e+01 1.48413159e+02]
# [ 4.03428793e+02 1.09663316e+03 2.98095799e+03]]
arr1 = np.arange(0, 10)
print(arr1)
# [0 1 2 3 4 5 6 7 8 9]
arr2 = np.array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])
print(arr2)
# [9 8 7 6 5 4 3 2 1 0]
# 相同位置取較大的元素
print(np.maximum(arr1, arr2))
# [9 8 7 6 5 5 6 7 8 9]
# 相同位置取較小的元素
print(np.minimum(arr1, arr2))
# [0 1 2 3 4 4 3 2 1 0]
print('-------------------------')
array = np.arange(0, 2, 0.5)
print(array)
# [ 0. 0.5 1. 1.5]
# 分別返回整數和小數
arr1, arr2 = np.modf(array)
print(arr1)
# [ 0. 0.5 0. 0.5]
print(arr2)
# [ 0. 0. 1. 1.]
# 其他還有很多之後用到了,再說吧
新加幾個Demo 和函式的用法
# Demo1
points = np.arange(-5, 5)
# points
# [-5 -4 -3 -2 -1 0 1 2 3 4]
xs, ys = np.meshgrid(points, points)
# xs
# [[-5 -4 -3 -2 -1 0 1 2 3 4]
# [-5 -4 -3 -2 -1 0 1 2 3 4]
# [-5 -4 -3 -2 -1 0 1 2 3 4]
# [-5 -4 -3 -2 -1 0 1 2 3 4]
# [-5 -4 -3 -2 -1 0 1 2 3 4]
# [-5 -4 -3 -2 -1 0 1 2 3 4]
# [-5 -4 -3 -2 -1 0 1 2 3 4]
# [-5 -4 -3 -2 -1 0 1 2 3 4]
# [-5 -4 -3 -2 -1 0 1 2 3 4]
# [-5 -4 -3 -2 -1 0 1 2 3 4]]
# ys
# [[-5 -5 -5 -5 -5 -5 -5 -5 -5 -5]
# [-4 -4 -4 -4 -4 -4 -4 -4 -4 -4]
# [-3 -3 -3 -3 -3 -3 -3 -3 -3 -3]
# [-2 -2 -2 -2 -2 -2 -2 -2 -2 -2]
# [-1 -1 -1 -1 -1 -1 -1 -1 -1 -1]
# [ 0 0 0 0 0 0 0 0 0 0]
# [ 1 1 1 1 1 1 1 1 1 1]
# [ 2 2 2 2 2 2 2 2 2 2]
# [ 3 3 3 3 3 3 3 3 3 3]
# [ 4 4 4 4 4 4 4 4 4 4]]
z = np.sqrt(xs ** 2 + ys ** 2)
print(z)
plt.imshow(z, cmap=plt.cm.gray);
plt.colorbar()
plt.title("Image")
plt.show()
# Demo2
xarr = np.array([1.1, 1.2, 1.3, 1.4, 1.5])
yarr = np.array([2.1, 2.2, 2.3, 2.4, 2.5])
cond = np.array([True, False, True, True, False])
print(np.where(cond, xarr, yarr))
# [ 1.1 2.2 1.3 1.4 2.5]
# Demo3
arr = np.array([[1, 2, 3], [4, 5, 6]])
# [[1 2 3]
# [4 5 6]]
# 累加 0代表列 1代表行
print(arr.cumsum(0))
# [[1 2 3]
# [5 7 9]]
print(arr.cumsum(1))
# [[ 1 3 6]
# [ 4 9 15]]
# 累乘
print(arr.cumprod(0))
# [[ 1 2 3]
# [ 4 10 18]]
print(arr.cumprod(1))
# [[ 1 2 6]
# [ 4 20 120]]