目錄
- 為什么使用numpy
- numpy矩陣的創建以及資料型別
- 直接使用np.array創建
- 使用numpy函式
- np.arange()、np.linspace()
- np.zeros() 、np.ones()、np.eye()
- np.empty()、np.zeros_like()、np.ones_like()
- 矩陣形狀
- 資料型別
- numpy矩陣的計算
- 廣播原則
- 數字計算
- 矩陣計算
- numpy中矩陣轉置
- numpy的切片、索引
- numpy中的數字的尋找與替換
- 矩陣的拼接
- 矩陣的行列交換
- 使用argmin與argmax獲取矩陣中最大最小值
- numpy生成亂數
- 亂數種子
- numpy中的nan與inf
- nan與inf
- 判斷矩陣中有多少個nan
- nan的替換
- numpy中常用統計函式
- numpy讀取資料
- 參考資料
import numpy as np
為什么使用numpy
numpy官方檔案
- python自帶list使用不方便,運行緩慢;
- numpy是python的計算拓展庫,開源,集成了一系列已編譯的數學和矩陣計算函式;
- numpy有獨有的資料結構,使用方便,運行快速;
- numpy資料占用空間小,讀取速度快,
numpy矩陣的創建以及資料型別
生成的型別為 numpy.ndarray,資料是線性的且連續存盤,
直接使用np.array創建
a = np.array([1, 2, 3])
使用numpy函式
np.arange()、np.linspace()
'''
np.arange([start,] stop[, step,], dtype = None)
'''
>>> np.arange(1, 5)
array([1, 2, 3, 4])
'''
numpy.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None, axis=0)
回傳間隔均勻的陣列
'''
# 生成了[0, 10]十一等分資料
>>> np.linspace(0, 10, 11)
array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.])
np.zeros() 、np.ones()、np.eye()
>>> np.zeros((3, 4))
array([[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.]])
>>> np.ones((3, 4))
array([[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]])
>>> np.eye(4) # 對角矩陣
array([[1., 0., 0., 0.],
[0., 1., 0., 0.],
[0., 0., 1., 0.],
[0., 0., 0., 1.]])
np.empty()、np.zeros_like()、np.ones_like()
'''
numpy.empty(shape, dtype=float, order='C')
回傳shape形狀的空矩陣
'''
>>> b = np.empty((3, 4))
>>> b
array([[6.89796323e-307, 2.78148153e-307, 2.78144588e-307,
1.60219035e-306],
[4.45064003e-308, 1.24611741e-306, 1.60219035e-306,
4.22791195e-307],
[3.44900369e-307, 4.00536722e-307, 2.33646845e-307,
4.00540457e-307]])
'''
numpy.zeros_like(a, dtype=None, order='K', subok=True, shape=None)
回傳和a矩陣形狀一樣的零矩陣
'''
>>> np.zeros_like(b)
array([[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.]])
'''
numpy.ones_like(a, dtype=None, order='K', subok=True, shape=None)
回傳和a矩陣形狀一樣的1矩陣
'''
>>> np.ones_like(b)
array([[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]])
矩陣形狀
numpy.shape,numpy.reshape()的運用,
# 矩陣的維度
>>> g = np.array([1, 2, 3], [4, 5, 6])
>>> g.shape
(2, 3)
>>> h = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])
array([[[ 1, 2, 3],
[ 4, 5, 6]],
[[ 7, 8, 9],
[10, 11, 12]]])
>>> h.shape
(2, 2, 3)
# 修改矩陣的形狀, 注意矩陣中的元素個數是相同的,2 * 2 * 3 = 2 * 6
# 當不知道具體矩陣的維度時,可以通過shape來獲取,h.shape[0], h.shape[1]
>>> h.reshape((2, 6))
array([[ 1, 2, 3, 4, 5, 6],
[ 7, 8, 9, 10, 11, 12]])
>>> h
array([[[ 1, 2, 3],
[ 4, 5, 6]],
[[ 7, 8, 9],
[10, 11, 12]]])
'''
注意reshape修改并未改變原來的矩陣,只是回傳了一個新的值!
'''
# 將一個多維陣列按行展開
>>> h.flatten()
array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
資料型別
numpy 支持的資料型別比 Python 內置的型別要多很多,基本上可以和 C 語言的資料型別對應上,常用Numpy資料型別可見此,
使用dtype可以查看numpy資料的型別,
'''
numpy.dtype(object, align, copy)
object: 要轉換為的資料型別物件
align: 如果為 true,填充欄位使其類似 C 的結構體,
copy: 復制 dtype 物件, 如果為 false,則是對內置資料型別物件的參考
所輸出的型別后的數字,若沒有修改,代表的是該資料的默認位數,
默認指定的位數考慮到了效率與便捷問題,一般是比較通用的情況,可以自行修改
'''
>>> b = np.arange(1, 5)
>>> b.dtype
dtype('int32')
>>> c = np.array(range(1, 6), dtype = float)
>>> c.dtype
dtype('float64')
>>> d = np.array(range(1, 6), dtype = "i1")
>>> d.dtype
dtype('int8')
'''
調整資料型別
'''
# eg: int8, int16, int32, int64 四種資料型別可以使用字串 'i1', 'i2','i4','i8' 代替
>>> e = d.astype("int8")
>>> e.dtype
dtype('int8')
# 取小數操作
>>> f = np.array([random.random() for i in range(7)])
>>> np.round(f, 2)
array([0.73, 0.92, 0.33, 0.77, 0.67, 0.98, 0.48])
numpy矩陣的計算
廣播原則
python的廣播原則:
如果兩個陣列的后緣維度(trailing dimension),即從末尾開始算起的維度的軸長度相符或其中一方的長度為1則認為它們是廣播兼容的,廣播會在缺失和(或)長度為1的維度上進行,
eg: shape為(1, 2, 3)的矩陣
- 其可以和shape為(3)的矩陣計算,在第一維度和第二維度上進行;
- 其可和shape為(2, 3)的矩陣計算,在第一維度上進行;
- 其不可和shape為(2, 4)的矩陣計算,
具體編程示例如下:
數字計算
# python numpy計算的廣播機制,整體變化
>>> i = np.arange(1, 13)
>>> i = i.reshape((3, 4))
>>> i
array([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12]])
>>> i + 3
array([[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
>>> i * 2
array([[ 2, 4, 6, 8],
[10, 12, 14, 16],
[18, 20, 22, 24]])
>>> j = i - 1
>>> j
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
>>> j / 0
array([[nan, inf, inf, inf],
[inf, inf, inf, inf],
[inf, inf, inf, inf]])
'''
此時python提示warning,但是仍然可以計算,nan表示不是一個數字,inf表示無窮大
'''
矩陣計算
# 矩陣計算,注意維度問題
'''
example 1
'''
>>> i + j
array([[ 1, 3, 5, 7],
[ 9, 11, 13, 15],
[17, 19, 21, 23]])
>>> i * j
array([[ 0, 2, 6, 12],
[ 20, 30, 42, 56],
[ 72, 90, 110, 132]])
'''
example 2-1
當其中某個為一維的時候,即這個維度不相等,此時也可計算, 但必須保證另一個維度相等
'''
>>> i
array([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12]])
>>> k = np.arange(1, 5)
>>> k
array([1, 2, 3, 4])
>>> i * k # 其中i形狀為(3, 4), k為(1, 4), 滿足廣播原則
array([[ 1, 4, 9, 16],
[ 5, 12, 21, 32],
[ 9, 20, 33, 48]])
>>> i + k
array([[ 2, 4, 6, 8],
[ 6, 8, 10, 12],
[10, 12, 14, 16]])
'''
example 2-2
'''
>>> l = np.array([[1], [2], [3]])
>>> l
array([[1],
[2],
[3]])
>>> i + l # i形狀為(3, 4), l的形狀為(3, 1), 長度為1, 滿足廣播機制
array([[ 2, 3, 4, 5],
[ 7, 8, 9, 10],
[12, 13, 14, 15]])
>>> i * l
array([[ 1, 2, 3, 4],
[10, 12, 14, 16],
[27, 30, 33, 36]])
'''
example 3
'''
>>> a = np.arange(18).reshape(3, 3, 2)
>>> b = np.arange(9).reshape(3, 3)
>>> a
array([[[ 0, 1],
[ 2, 3],
[ 4, 5]],
[[ 6, 7],
[ 8, 9],
[10, 11]],
[[12, 13],
[14, 15],
[16, 17]]])
>>> b
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
>>> a + b
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: operands could not be broadcast together with shapes (3,3,2) (3,3)
'''
出現報錯!
不滿足廣播機制,(3, 3, 2)與(3, 3)的矩陣不能夠進行運算!
'''
'''
當b修改為如下時(3, 3, 1)即可進行運算!(3, 3, 2)與(3, 3, 1)
'''
>>> b = np.arange(9).reshape(3, 3, 1)
>>> b
array([[[0],
[1],
[2]],
[[3],
[4],
[5]],
[[6],
[7],
[8]]])
>>> a + b
array([[[ 0, 1],
[ 3, 4],
[ 6, 7]],
[[ 9, 10],
[12, 13],
[15, 16]],
[[18, 19],
[21, 22],
[24, 25]]])
numpy中矩陣轉置
a = np.arange(12).reshape((3, 4))
# 法一:
a.transponse()
# 法二:
a.T
# 法三:交換軸
a.swapaxes(1, 0)
numpy的切片、索引
>>> a = np.arange(12).reshape((3, 4))
>>> a
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
>>> a[1:3] # 取行
array([[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
>>> a[:, 2:4] # 取列
array([[ 2, 3],
[ 6, 7],
[10, 11]])
>>> a[[0, 2]] # 不連續的多行
array([[ 0, 1, 2, 3],
[ 8, 9, 10, 11]])
>>> a[[0, 2], [1, 3]] # 多個點
array([ 1, 11])
'''
注意雖然取的是整數,但是并不是之前的int32型別
'''
>>> type(a[1, 2])
<class 'numpy.int32'>
numpy中的數字的尋找與替換
>>> a = np.arange(12).reshape((3, 4))
>>> a
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
>>> a < 5
array([[ True, True, True, True],
[ True, False, False, False],
[False, False, False, False]])
'''
法一:使用邏輯判斷True和False,將a矩陣中所有小于5的數替換為6
'''
>>> a[a < 5] = 6
>>> a
array([[ 6, 6, 6, 6],
[ 6, 5, 6, 7],
[ 8, 9, 10, 11]])
>>> a = np.arange(12).reshape((3, 4))
>>> a[a < 5] # 注意區分這個和上面賦值
array([0, 1, 2, 3, 4])
'''
法二:使用where函式
numpy.where(condition[, x, y])
根據條件回傳從x或y中選擇的元素
'''
# 將矩陣a中所有小于5的數替換為6,大于5的數替換為1
>>> np.where(a < 5, 6, 1)
array([[6, 6, 6, 6],
[6, 1, 1, 1],
[1, 1, 1, 1]])
'''
法三:使用clip函式
numpy.clip(a, a_min, a_max, out=None, **kwargs)
給定一個區間,區間外的值被裁剪到區間的邊界上,
舉例來說,給定區間[a, b],大于b的變成b,小于a的變成a
'''
# numpy中的clip,大于8的變為8,小于5的變成5
>>> a.clip(5, 8)
array([[5, 5, 5, 5],
[5, 5, 6, 7],
[8, 8, 8, 8]])
'''
numpy矩陣含有inf、nan的型別轉換
'''
>>> a[2, 3] = np.nan
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: cannot convert float NaN to integer
# 需要對numpy矩陣型別進行轉換,如下即可
>>> a = a.astype(float)
>>> a
array([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.]])
>>> a[2, 3] = np.nan
>>> a
array([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., nan]])
矩陣的拼接
>>> a = np.arange(12).reshape((3, 4))
>>> a
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
>>> b = np.arange(12, 24).reshape((3, 4))
>>> b
array([[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]])
'''
豎直拼接,注意豎直分割是這個方向
'''
>>> np.vstack((a, b))
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]])
'''
水平拼接,注意水平分割是這個方向
'''
>>> np.hstack((a, b))
array([[ 0, 1, 2, 3, 12, 13, 14, 15],
[ 4, 5, 6, 7, 16, 17, 18, 19],
[ 8, 9, 10, 11, 20, 21, 22, 23]])
矩陣的行列交換
>>> a = np.arange(12).reshape((3, 4))
>>> a
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
# 行交換
>>> a[[0, 1], :] = a[[1, 0], :]
>>> a
array([[ 4, 5, 6, 7],
[ 0, 1, 2, 3],
[ 8, 9, 10, 11]])
# 列交換
>>> a[:, [0, 1]] = a[:, [1, 0]]
>>> a
array([[ 5, 4, 6, 7],
[ 1, 0, 2, 3],
[ 9, 8, 10, 11]])
使用argmin與argmax獲取矩陣中最大最小值
>>> c = np.array([random.randint(1, 100) for i in range(12)]).reshape((3, 4))
>>> c
array([[ 66, 100, 19, 48],
[ 95, 68, 81, 9],
[ 60, 80, 12, 63]])
'''
獲取最大值位置
'''
>>> np.argmax(c) # 相當于陣列為一維的時索引
1
>>> np.argmax(c, axis = 0) # 取的為每一列的最大值
array([1, 0, 1, 2], dtype=int64)
'''
獲取最小值位置
'''
>>> np.argmin(c) # 相當于陣列為一維的時索引
7
>>> np.argmin(c, axis = 1) # 取得為每一行的最小值
array([2, 3, 2], dtype=int64)
numpy生成亂數
| 引數 | 說明 |
|---|---|
| .rand(d0, d1, …, dn) | 創建d0—dn維度的均勻分布的亂數陣列,范圍為[0, 1),浮點數 |
| .randn(d0, d1, …, dn) | 創建d0—dn維度、滿足均值為0、方差為1的標準正態分布亂數陣列,未給定引數的情況下,回傳從分布中隨機采樣的單個浮點數 |
| .randint(low, high=None, size=None, dtype=int) | 從指定dtype的離散均勻分布[low, high)中回傳隨機整數,如果沒有指定high,默認區間為[0, low) |
| .uniform(low=0.0, high=1.0, size=None) | 樣本均勻分布在區間[low, high),從其中抽取樣本 |
| .normal(loc=0.0, scale=1.0, size=None) | 從正態分布中抽取隨機樣本,loc為均值,scale為標準差 |
| .seed(self, seed=None) | 亂數種子,seed是給定的種子值,通過設定相同的亂數種子,可以每次生成相同的亂數(計算機生成的是偽亂數) |
>>> np.random.rand(3,4)
array([[0.6350389 , 0.42583308, 0.83244198, 0.13534336],
[0.1646268 , 0.08109012, 0.31921804, 0.58858143],
[0.16737554, 0.22531111, 0.89541298, 0.35630342]])
亂數種子
import numpy as np
i = 0
while i < 5:
np.random.seed(3)
print(np.random.rand(1, 2))
i = i + 1
上述代碼輸出為:
[[0.5507979 0.70814782]]
[[0.5507979 0.70814782]]
[[0.5507979 0.70814782]]
[[0.5507979 0.70814782]]
[[0.5507979 0.70814782]]
對代碼修改如下:
import numpy as np
i = 0
np.random.seed(3)
while i < 5:
print(np.random.rand(1, 2))
i = i + 1
輸出為:
[[0.5507979 0.70814782]]
[[0.29090474 0.51082761]]
[[0.89294695 0.89629309]]
[[0.12558531 0.20724288]]
[[0.0514672 0.44080984]]
兩者的區別在于亂數種子的設定位置不同,亂數種子設定一定的時候,產生的亂數一樣,但后者是將亂數種子的設定放到了回圈之外,使得除第一次回圈之外,其余的軍事重新生成的亂數種子,于是生成的每次結果均不相同,
numpy中的nan與inf
nan與inf
nan(not a number):表示并非一個數字,它和任何值計算的結果都是nan,典型出現情況如下:
- 當計算不恰當時(如0/0,且結果不為inf/-inf),則會出現nan;
- 當讀取本地float檔案出現缺失時
inf(infinity / - infinity):無窮大(正負),出現典型情況是非0的數a除以0,其出現在python中會直接報錯,如下:
>>> 1/0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero
注意 np,inf 與 np.nan 均為float型別
# 兩個np.nan不相等
>>> np.nan == np.nan
False
判斷矩陣中有多少個nan
'''
法一:可以利用numpy中count_nonzero函式來判斷矩陣中有幾個nan
numpy.count_nonzero(a, axis=None, *, keepdims=False)
對陣列a中的非零值進行計數
'''
>>> a
array([[ 5., 4., 6., 7.],
[ 1., 0., nan, 3.],
[ 9., nan, 10., 11.]])
>>> a != a
array([[False, False, False, False],
[False, False, True, False],
[False, True, False, False]])
>>> np.count_nonzero(a != a)
2
'''
法二:利用np.isnan()函式
numpy.isnan(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) = <ufunc 'isnan'>
測驗陣列中是否有元素nan,并以布爾陣列的形式回傳結果
'''
>>> np.isnan(a)
array([[False, False, False, False],
[False, False, True, False],
[False, True, False, False]])
>>> np.count_nonzero(np.isnan(a))
2
'''
nan和任何值作計算,結果均為nan
'''
>>> a
array([[ 5., 4., 6., 7.],
[ 1., 0., nan, 3.],
[ 9., nan, 10., 11.]])
>>> np.sum(a)
nan
>>> np.sum(a, axis = 0)
array([15., nan, nan, 21.])
>>> np.sum(a, axis = 1)
array([22., nan, nan])
nan的替換
nan在讀取資料中通常是缺失值,一般把nan替換為均值,或者是直接洗掉有nan的那一行/列,
numpy中常用統計函式
| 函式 | 功能 |
|---|---|
| np.sum(a) 、a.sum() | 求和 |
| np.mean(a)、a.mean() | 均值 |
| np.median(a) | 中值 |
| np.max(a)、a.max() | 最大值 |
| np.min(a)、a.min() | 最小值 |
| np.ptp(a)、a.ptp() | 極值 |
| np.std(a)、a.std() | 標準差 |
numpy讀取資料
分析資料的思路:看到這個問題,我們應該怎么思考?
- 想要得出什么結論,解決什么問題?
- 選擇什么樣的呈現方式?
- 資料還需要做什么樣的處理?
- 撰寫代碼
numpy.loadtxt的說明檔案
numpy.loadtxt(fname, dtype=<class 'float'>, comments='#', delimiter=None, converters=None, skiprows=0, usecols=None, unpack=False, ndmin=0, encoding='bytes', max_rows=None)
引數含義如下:
| 引數 | 解釋 |
|---|---|
| frame | 需要讀取的檔案 |
| dtype | 讀取陣列的資料型別,默認為浮點數 |
| comments | 用來表示注釋開始的字符,默認為# |
| delimiter | 用于分隔值的字串,默認為空格 |
| skiprows | 跳過幾行開始讀數,包括注釋 |
| usecols | 要讀取的列,第一列為0,默認值為None,讀取所有 |
| unpack | 如果為True,回傳的陣列將會被轉置,便于將屬性分別寫入不同的陣列變數,默認為False,僅僅寫入一個陣列變數 |
| ndmin | 回傳的陣列至少有ndmin維度,否則,一維軸將被壓縮,值可取0(默認值),1,2 |
| encoding | 用于解碼輸入檔案的編碼,默認為bytes |
| max_rows | 從跳過行數之后開始,讀取的最多行數,默認情況下讀取所有行 |
(等有時間可以整理更完善些,)
參考資料
- https://numpy.org/doc/stable/reference/generated/numpy.isnan.html?highlight=isnan#numpy.isnan
- https://stackoverflow.com/questions/41774047/using-numpy-to-square-value-gives-negative-number
- https://www.runoob.com/numpy/numpy-dtype.html
- 視頻教程
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/234259.html
標籤:python
上一篇:路徑規劃演算法學習Day3
