numpy
可以幫助我們處理數值型的數據,注意,是數值型
用於處理數組(或者叫做矩陣)
創建數組(或矩陣)
可以先簡單的通過列表創建數組
import numpy as np
t1 = np.array([1,2,3])
print(t1)
print(type(t1))
來看看輸出了什麼
打印出了一個像列表的數據,但是中間沒有逗號~
還有其他一些簡單的創建方式
import numpy as np
t1 = np.array([1,2,3])
print(t1)
print(type(t1))
t2 = np.array(range(10))
print(t2)
t3 = np.arange(10)
print(t3)
我們可以發現t2和t3其實是一樣的,類型也都是和t1一樣的
當然np.arange()
也可以像range()
一樣取步長
數組元素的數據類型
我們並沒有指定這些元素的數據類型
我們來看看它們裏面元素的數據類型(因電腦位數不同而會有所不同)
import numpy as np
t1 = np.array([1,2,3])
print(t1)
print(type(t1))
t2 = np.array(range(10))
print(t2)
t3 = np.arange(10)
print(t3)
# 查看數組元素的數據類型
print(t3.dtype)
這裏打印出是int32位的
還有其他更多的數據類型
在實際形況中,我們可以指定數組裏面的數據類型,可以達到節省空間的目的
創建時指定數據類型
array()
函數裏面有個dtype
參數可以指定元素的數據類型
import numpy as np
t1 = np.array([1,2,3])
print(t1)
print(type(t1))
t2 = np.array(range(10))
print(t2)
t3 = np.arange(10)
print(t3)
# 查看數組元素的數據類型
print(t3.dtype)
print("*"*50)
# 指定數據類型
t4 = np.array(range(1,4),dtype='float32')
print(t4)
print(t4.dtype)
好像這個bool類型的蠻有趣的,我們來看看它是怎麼樣的
import numpy as np
t1 = np.array([1,2,3])
print(t1)
print(type(t1))
t2 = np.array(range(10))
print(t2)
t3 = np.arange(10)
print(t3)
# 查看數組元素的數據類型
print(t3.dtype)
print("*"*50)
# 指定數據類型
t4 = np.array(range(1,4),dtype='float32')
print(t4)
print(t4.dtype)
# numpy中的bool類型
t5 = np.array([1,1,0,1,0,0],dtype=bool)
print(t5)
print(t5.dtype)
打印出來效果是這樣的
調整數據類型
需要astype()
函數,裏面傳入調整後的數據類型就好了
import numpy as np
t1 = np.array([1,2,3])
print(t1)
print(type(t1))
t2 = np.array(range(10))
print(t2)
t3 = np.arange(10)
print(t3)
# 查看數組元素的數據類型
print(t3.dtype)
print("*"*50)
# 指定數據類型
t4 = np.array(range(1,4),dtype='float32')
print(t4)
print(t4.dtype)
# numpy中的bool類型
t5 = np.array([1,1,0,1,0,0],dtype=bool)
print(t5)
print(t5.dtype)
t6 = t5.astype('int8')
print(t6)
print(t6.dtype)
numpy中的小數
np.round()
可以幫助取幾位小數
import numpy as np
import random
t1 = np.array([1,2,3])
print(t1)
print(type(t1))
t2 = np.array(range(10))
print(t2)
t3 = np.arange(10)
print(t3)
# 查看數組元素的數據類型
print(t3.dtype)
print("*"*50)
# 指定數據類型
t4 = np.array(range(1,4),dtype='float32')
print(t4)
print(t4.dtype)
# numpy中的bool類型
t5 = np.array([1,1,0,1,0,0],dtype=bool)
print(t5)
print(t5.dtype)
t6 = t5.astype('int8')
print(t6)
print(t6.dtype)
# numpy中的小數
t7 = np.array([random.random() for i in range(10)])
print(t7)
print(t7.dtype)
t8 = np.round(t7,2)
print(t8)
數組的形狀
什麼是數組的形狀?
先來看個例子
import numpy as np
t1 = np.arange(12)
print(t1)
print(t1.shape)
t2 = np.array([[1,2,3],[4,5,6]])
print(t2)
print(t2.shape)
原來數組的形狀就是它是描述它的緯度
一維的數組打印出來只有一個數字,二維的兩個數組打印出來有兩個數字
那三維的是不是三個呢,我們來看看
import numpy as np
# 一維
t1 = np.arange(12)
print(t1)
print(t1.shape)
# 二維
t2 = np.array([[1,2,3],[4,5,6]])
print(t2)
print(t2.shape)
# 三維
t3 = np.array([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]])
print(t3)
print(t3.shape)
三維打印出來的(2, 2, 3), 第一個2表示塊數,相當於是空間座標的Z軸,後面的(2,3)就是平面的2行3列
調整數組的緯度
我們可以將一維的變成2維的,也可以將2維的變成一維的
用到了reshape()
函數
import numpy as np
t4 = np.array(range(12))
print(t4)
t4 = t4.reshape(3,4)
print(t4)
當然轉換的要求要保證前後數量一致,不然就報錯
一維轉三維
import numpy as np
t5 = np.arange(24).reshape((2,3,4))
print(t5)
三維的轉二維的
import numpy as np
t5 = np.arange(24).reshape((2,3,4))
print(t5)
print(t5.reshape(4,6))
轉換的過程大概是三維的先壓平成一維的,然後從一維的變成二維的
二維邊一維
import numpy as np
t5 = np.arange(24).reshape((2,3,4))
t6 = t5.reshape(4,6)
t7 = t6.reshape(24,)
print(t7)
想一想,爲什麼不是t6.reshape(1,24)
我們來打印一下結果你就會發現它其實是二維的
如果有一個二維數組非常大,我想把它變成一維,是不是要知道元素的個數
在二維數組中,shape[0]
表示有多少行,shape[1]
表示有多少列
那麼我們可以這樣
t6 = t5.reshape(t5.shape[0]*t5.shape[1],)
還有一種簡便的方法變成一維
有個函數叫做flatten()
,碾平的意思
這種方式不需要傳入元素的個數
import numpy as np
t5 = np.arange(24).reshape((2,3,4))
t6 = t5.reshape(4,6)
t7 = t6.flatten()
print(t7)
數組的計算
一個數組和一個數計算,所有的元素都會與它運算
import numpy as np
t5 = np.arange(24).reshape((2,3,4))
t6 = t5.reshape(4,6)
print(t6)
t7 = t6 + 1
print(t7)
如果除於0呢,看看會不會出問題
import numpy as np
t5 = np.arange(24).reshape((2,3,4))
t6 = t5.reshape(4,6)
print(t6)
t7 = t6/0
print(t7)
程序只是報了warning,還是可以顯示的,只是這結果不對勁呀
nan
意思not a number, 它不是一個數,可以是其他東西,比如字符串,香蕉蘋果啥的
inf
意思是無窮大的意思,還有-inf是無窮小
一個數組和一個相同形狀的數組運算,對應位置獨立運算,這個很好理解
如果是不同緯度的數組相互計算,如果存在某個維度上一致,那麼是可以計算的
我們來看看
import numpy as np
t1 = np.arange(6)
t2 = np.array([np.arange(6),np.arange(6,12),np.arange(12,18)])
print(t1)
print(t2)
那麼這兩個數組可以計算嗎?
是可以的,因爲在行的方向上的緯度是一樣的
import numpy as np
t1 = np.arange(6)
t2 = np.array([np.arange(6),np.arange(6,12),np.arange(12,18)])
print(t1)
print(t2)
print(t1+t2)
如果是列方向緯度一致,也是一樣的
三維的和二維的計算也是同一個道理
軸
在numpy中可以理解爲方向,用0,1,2數字表示
對於一個一維數組,只有一個0軸
二維數組,有0軸和1軸,0軸表示行方向,1軸表示列方向
三維數組,有0,1,2軸,0表示高度(Z軸),1表示行方向,2表示列方向
轉置
numpy中轉置有多種方法,這裏介紹常用的兩種方法
第一種是transpose()
第二種是屬性T
import numpy as np
t1 = np.arange(12).reshape(3,4)
print(t1)
print(t1.transpose())
print(t1.T)
索引和切片
numpy中索引從0開始的
取某一行,注意取出來的是一維的
import numpy as np
t1 = np.arange(24).reshape(4,6)
print(t1)
print("*"*50)
# 取第三行
print(t1[2])
取連續的多行
import numpy as np
t1 = np.arange(24).reshape(4,6)
print(t1)
print("*"*50)
# 取第2: 3 行
print(t1[1:3])
取不連續的多行
都加了一個方括號
import numpy as np
t1 = np.arange(24).reshape(4,6)
print(t1)
print("*"*50)
# 取第2行和第4行
print(t1[[1,3]])
取某一列,注意選出來的是一維的
import numpy as np
t1 = np.arange(24).reshape(4,6)
print(t1)
print("*"*50)
# 取第1列
print(t1[:,0])
取連續的幾列
import numpy as np
t1 = np.arange(24).reshape(4,6)
print(t1)
print("*"*50)
# 取第2:4列
print(t1[:,1:4])
取不連續的多列
import numpy as np
t1 = np.arange(24).reshape(4,6)
print(t1)
print("*"*50)
# 取第1列和第3列
print(t1[:,[0,2]])
取多行多列
import numpy as np
t1 = np.arange(24).reshape(4,6)
print(t1)
print("*"*50)
# 取第3行第4列的值,雖然是一個數但類型要注意
a = t1[2,3]
print(a)
print(type(a))
# 取第2:4行,第3到第6列
print(t1[1:4,2:6])
# 取多個不相鄰的點,有些特殊
# 取(0,2),(3,1)值
print(t1[[0,3],[2,1]])
對數組的修改
import numpy as np
t1 = np.arange(24).reshape(4,6)
print(t1)
print("*"*50)
t1[:,1:3] = 0
print(t1)
如果要把數組中小於10的修改爲10怎麼寫?
先看下面程序
import numpy as np
t1 = np.arange(24).reshape(4,6)
print(t1)
print("*"*50)
print(t1<10)
可以看出那些是小於10的,這就是很常用的bool索引
如果要把數組中小於10的修改成10,那麼這就很簡單了
t1[t1<10] = 10
如果想把小於10的改爲0,大於10的改爲10
按照上面的方法,我們要寫兩行
這裏介紹一個where()
函數,一行就能解決
import numpy as np
t1 = np.arange(24).reshape(4,6)
print(t1)
print("*"*50)
print(np.where(t1<10,0,10))
問題升級
如果我想把小於10的改爲10,大於20的改爲20呢?
當然bool索引可以做,也是寫兩行
這裏介紹一個clip()
裁剪函數
import numpy as np
t1 = np.arange(24).reshape(4,6)
print(t1)
print("*"*50)
print(t1.clip(10,18))
nan和inf
nan就是not a number,表示不是一個數字
numpy中出現nan的情況:
當我們讀取本地文件爲float的時候,如果有缺少,就會出現nan
當做了一個不合適的計算的時候,比如( 無窮大(inf)減去無窮大)
inf表示正無窮,-inf表示負無窮
什麼時候會出現inf:
當一個數字處於0 (python中會直接報錯,而numpy會出現inf)
在numpy中如何指定一個數爲nan和inf
import numpy as np
a = np.nan
print(a)
print(type(a))
b = np.inf
print(b)
print(type(b))
發現它們都是float
類型
numpy中nan的注意點
兩個nan是不想等的
import numpy as np
print(np.nan == np.nan)
這個性質有一些特殊用途
比如,可以判斷數組中nan的個數
先介紹count_nonzero()
數組是統計非0的個數
import numpy as np
a = np.arange(12).reshape(3,4).astype('float')
a[2,3] = np.nan
print(a)
print(a!=a)
# 統計a中nan的個數
print(np.count_nonzero(a!=a))
還可以這樣統計nan的個數
import numpy as np
a = np.arange(12).reshape(3,4).astype('float')
a[2,3] = np.nan
print(a)
print(np.isnan(a))
# 統計a中nan的個數
print(np.count_nonzero(np.isnan(a)))
這樣可以把爲nan的地方換成別的值,比如0
a[np.isnan(a)] = 0
nan和任意值運算都爲nan
這裏介紹一個np.sum()
函數,統計和的
import numpy as np
a = np.arange(12).reshape(3,4).astype('float')
a[2,3] = np.nan
print(a)
# 計算數組a的和
print(np.sum(a))
# 計算行方向上的值
print(np.sum(a,axis=0))
因爲nan不能參與計算,那麼一般都是把nan替換次別的值
有些時候單純的替換成0是不合適的
更一般是替換成均值(中值),或者直接刪去
那麼問題來了
怎麼計算一組數據的中值或均值?
如何刪除有缺失的那一行(列) ?【在pandas中介紹】
numpy中常用的統計函數
將數組中nan填充爲均值
import numpy as np
def fill_ndarray(t1):
'''
把數組中有nan的地方填充爲均值
:param t1: 原始的二維數組
:return: 填充之後的數組
'''
# 遍歷所有列
for i in range(t1.shape[1]):
# 當前列
cur_col = t1[:,i]
# 當前列中nan的個數
num_not_nan = np.count_nonzero(cur_col!=cur_col)
# 如果當前列有nan
if num_not_nan != 0:
# 當前列不爲nan的ndarray
array_not_nan = cur_col[cur_col==cur_col]
# 把nan的位置賦值爲均值
cur_col[np.isnan(cur_col)] = array_not_nan.mean()
return t1
if __name__ == '__main__':
# 創建一個二維數組,類型爲float
t1 = np.arange(12).reshape(3,4).astype('float')
# 將t1數組裏面部分值賦值爲nan
t1[1,2:] = np.nan
print(t1)
t1 = fill_ndarray(t1)
print(t1)
數組拼接
豎直拼接np.vstack()
水平拼接np.hstack()
注意傳入的是一個元組,就是有兩層括號
import numpy as np
t1 = np.arange(10).reshape(2,5)
t2 = np.arange(10,20).reshape(2,5)
print(t1)
print(t2)
# 豎直拼接np.hstack((t1,t2))
t3 = np.vstack((t1,t2))
print(t3)
# 水平拼接
print(np.hstack((t1,t2)))
數組的行列交換
import numpy as np
t1 = np.arange(12).reshape(3,4)
print(t1)
# 第2行和第3行交換
t1[[1,2],:] = t1[[2,1],:]
print(t1)
#第1列和第3列交換
t1[:,[0,2]] = t1[:,[2,0]]
print(t1)
numpy更多好用的方法
創建一個全0的數組 np.zeros((3,4))
創建一個全1的數組 np.ones((3,4))
創建一個對角線爲1的方陣 np.eye(5)
獲取數組最大值,最小值的位置,可以指定方向
import numpy as np
t = np.array([[3,5,1,0],[6,3,8,9]])
print(t)
print(t.argmax())
print(t.argmax(axis=1))
print(t.argmin(axis=0))
隨機數
numpy的注意點copy和view
- a=b完全不復制,a和b相互影響,即a和b共享一塊內存
- a = b[:] ,視圖操作,也是完全不復制
- a = b.copy(), 深拷貝,a和b互不影響