用python進(jìn)行數(shù)據(jù)分析, 一般都離不開(kāi)兩個(gè)庫(kù):Numpy 和 pandas。這本書之前刷過(guò)一半, 太久沒(méi)看, 細(xì)節(jié)忘卻,這次重拾, 順便記錄之。
前言
-
NumPy本身并沒(méi)有提供那么多高級(jí)的數(shù)據(jù)分析的功能,但理解Numpy數(shù)數(shù)組結(jié)構(gòu),能更好的理解以及以及運(yùn)用Pandas,所以, 還是從Numpy開(kāi)始搞起,等學(xué)起pandas還是能省不少力的。 -
ndarray:Numpy中的多維數(shù)組隊(duì)對(duì)象(可類比與矩陣),用numpy操作數(shù)據(jù)的時(shí)候, 基本上也是操作ndarry。其中的運(yùn)算也跟高數(shù)中的矩陣非常像,ndarry是一個(gè)通用的同構(gòu)數(shù)據(jù)多維容器, 其中的所有的元素必須是相同的類型,所有的元素必須是相同的類型,所有的元素必須是相同的類型(重說(shuō)三)。 - 慣例中引入numpy的方法:
import numpy as np,建議大家養(yǎng)成這個(gè)習(xí)慣, 因?yàn)榛径际沁@么做的。 - 先來(lái)明確一下
ndarray、array和矩陣:首先ndarray即數(shù)組。np.array只是numpy一個(gè)便捷的函數(shù),用來(lái)創(chuàng)建一個(gè)ndarray。矩陣是線性代數(shù)中的概念, 其中的元素必須是數(shù)字,而ndarray中的的元素可以為字符串。 - 以下的操作均在
jupyter中進(jìn)行,以后的文章也是。
1.創(chuàng)建一個(gè)ndarrynp.aarray
import numpy as np
# 創(chuàng)建ndarray
# 1.list轉(zhuǎn)換
temp_list = [1,2,3]
np.array(temp_list) # 返回一維 array([1, 2, 3])
temp_list2 = [[1,2,3],[4,5,6]]
np.array(temp_list2) # 返回ndarray array([[1, 2, 3], [4, 5, 6]])
np.array2string(np.array(temp_list)) # 轉(zhuǎn)換成字符串 返回值 '[1 2 3]'
#2.直接生成
# 創(chuàng)建全0的ndarray
np.zeros(10) # 返回值 array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
np.zeros((3,6)) # 接收的(3,6)為array的形狀 返回值 array([[0., 0., 0., 0., 0., 0.],
# [0., 0., 0., 0., 0., 0.],
# [0., 0., 0., 0., 0., 0.]])
np.zeros_like(np.array([1,2,3])) # 返回形狀相同的全0數(shù)組,array([0, 0, 0])
# 創(chuàng)建隨機(jī)的ndarray, array數(shù)據(jù)是一些未初始化的垃圾值。
np.empty((2,1)) # 返回值 array([[ 1.49166815e-154], [-2.00390439e+000]])
# 類似range, 返回的是
np.arange(5) # 返回值 array([0, 1, 2, 3, 4])
# 創(chuàng)建全1的ndarray
np.ones(3) #返回值 array([1., 1., 1.])
np.ones((2,3)) # 接收的(2,3)為array的形狀,返回值 array([[1., 1., 1.], [1., 1., 1.]])
np.ones_like(np.array([1,2,3])) # 返回形狀相同的全1數(shù)組,array([1, 1, 1])
# 創(chuàng)建N*N的ndarray
np.eye(3) # 創(chuàng)建3*3正方形矩陣,對(duì)角線為1,其余為0.的array。 array([[1., 0., 0.],
# [0., 1., 0.],
# [0., 0., 1.]])
np.identity(3) # 同 eye. array([[1., 0., 0.],
# [0., 1., 0.],
# [0., 0., 1.]])
# 從字符串中獲取
temp_str = '1,2,3,4'
np.fromstring(temp_str,sep=',') # 返回值:array([1., 2., 3., 4.])
2.ndarray的結(jié)構(gòu)軸(axes)和秩(rank)
軸:每一個(gè)線性的數(shù)組稱為是一個(gè)軸,也就是維度(dimensions)。
秩:維數(shù),一維數(shù)組的秩為1,二維數(shù)組的秩為2,以此類推。即軸的個(gè)數(shù)。
temp_array = np.eye(5) # 創(chuàng)建一個(gè)5*5的數(shù)組
temp_array.shape # 顯示數(shù)組在每個(gè)維度上的大小,返回值一個(gè)元組(5,5) 即5行5列的2維數(shù)組。
temp_array.ndim #顯示數(shù)組的秩, 返回值為2, 即 len(temp_array.shape)
# 三維數(shù)組
temp_list3 = [[[1,2,3],[3,4,5]],
[[5,6,7], [7,8,9]]]
temp_array3 = np.array(temp_list3)
temp_array3.shape # 顯示數(shù)組在每個(gè)維度上的大小,返回值是 (2, 2, 3),即結(jié)構(gòu)為2*2*3的3維數(shù)組
temp_array3.ndim # 返回3, 即秩為3
temp_array3[1] # 返回下標(biāo)為1的元素, 即[[5 6 7], [7 8 9]]
3.ndarry的數(shù)據(jù)類型dtype
dtype(數(shù)據(jù)類型)是一種特殊的對(duì)象, 它含有ndarry將一塊內(nèi)存解釋為特定的數(shù)據(jù)類型所需的信息。dtype是Numpy如此強(qiáng)大和靈活的原因之一。
來(lái)自圖書作者的提示:記不住這些NumPy的dtype也沒(méi)關(guān)系。 通常只需知道你所處理的數(shù)據(jù)的大致類型是:浮點(diǎn)數(shù)、復(fù)數(shù)、整數(shù)、布爾值、字符串,還是普通的Python對(duì)象即可。當(dāng)你需要控制數(shù)據(jù)在內(nèi)存和磁盤中的存儲(chǔ)方式時(shí)(尤其是對(duì)大數(shù)據(jù)集),那就得了解如何控制存儲(chǔ)的類型。
#np.array默認(rèn)的類型
temp_list = ['1','2','3']
temp_array = np.array(temp_list)
temp_array.dtype #dtype('<U1')
temp_list2 = [1,2,3,4]
temp_array2 = np.array(temp_list2)
temp_array2.dtype #dtype('int64')
temp_list3 = [1.,2.,3.]
temp_array3 = np.array(temp_list3)
temp_array3.dtype #dtype('float64')
temp_list4 = [True, False]
temp_array4 = np.array(temp_list4)
temp_array4.dtype # dtype('bool')
temp_list5= ['董小賤','小菜雞']
temp_array5 = np.array(temp_list5)
temp_array5.dtype # dtype('<U3')
temp_list6 = ['a','b','c']
temp_list6 = np.array(temp_list6)
temp_list6.dtype # dtype('<U1')
temp_list7 = [-1,0,-3]
temp_list7 = np.array(temp_list7)
temp_list7.dtype # dtype('int64')
#創(chuàng)建指定類型的ndarray
temp_list8 = [1,2,3,4]
temp8 = np.array(temp_list8) # 默認(rèn)類型
temp8.dtype #dtype('int64') temp8的值為 array([1, 2, 3, 4])
temp_array8 = np.array(temp_list8, dtype=np.int32)
temp_array8.dtype #dtype('int32') temp_array8的值為 array([1, 2, 3, 4], dtype=int32)
temp_array9 = np.array(temp_list8, dtype=np.float32)
temp_array9.dtype #dtype('int32') temp_array9的值為:array([1., 2., 3., 4.], dtype=float32)
temp_array10 = np.array(temp_list8, dtype=np.uint8)
temp_array10.dtype #dtype('uint8') temp_array10 的值為 array([1, 2, 3, 4], dtype=uint8)
numpy中的數(shù)據(jù)類型(也可參考《利用python進(jìn)行數(shù)據(jù)分析》)

數(shù)據(jù)類型.png
numpy中的類型轉(zhuǎn)換astype
# 數(shù)據(jù)類型轉(zhuǎn)換
temp_list11 = [1,2,3,4]
temp_array11 = np.array(temp_list11)
temp_array11.dtype #dtype('int64')
temp_array12 = temp_array11.astype(np.float64) #這里是返回一個(gè)新的數(shù)組, 而不是改變舊的數(shù)組 array([1., 2., 3., 4.])
temp_array11.dtype #dtype('int64')
temp_array12.dtype #dtype('float64')
temp_list13 = [1.1,2.2,3.1]
temp_list13 = np.array(temp_list13)
temp_list13.astype(int) # array([1, 2, 3]) dtype類型為 dtype('int64')
注:如果astype的參數(shù)寫int,float, 將會(huì)使用默認(rèn)的int64, 以及float64類型, 建議使用np.int64這種方式, 一目了然。
# 另類操作,直接給數(shù)組的dtype賦值,原始數(shù)據(jù)直接改變, 一般不會(huì)使用這種方式,改變dtype類型,還是使用astype
temp_list13 = [1.1,2.2,3.1]
temp_list13 = np.array(temp_list13)
temp_list13 #array([1.1, 2.2, 3.1])
temp_list13.dtype='int64'
temp_list13 # array([4607632778762754458, 4612136378390124954, 4614162998222441677])
temp_list13.dtype = 'int32'
temp_list13 # array([-1717986918, 1072798105, -1717986918, 1073846681, -858993459,1074318540], dtype=int32)
4.數(shù)組標(biāo)量之間的運(yùn)算(可類比于矩陣的運(yùn)算法則,請(qǐng)注意區(qū)別)
標(biāo)量:只有大小,沒(méi)有方向,即一個(gè)數(shù)字。
矢量:有大小,有方向,比如數(shù)組。
數(shù)組可以不用編寫循環(huán)即可對(duì)數(shù)據(jù)進(jìn)行批量運(yùn)算,這通常叫作矢量化。大小相等的數(shù)組之間的任何算數(shù)運(yùn)算都將會(huì)應(yīng)用的元素級(jí)。
temp_list = [1,2,3,4,5,6]
temp_array = np.array(temp_list)
temp_list2 = [6,5,4,3,2,1]
temp_array2 = np.array(temp_list2)
temp_array * temp_array2 #返回值: array([ 6, 10, 12, 12, 10, 6])
temp_list2 + temp_array #返回值 array([7, 7, 7, 7, 7, 7])
temp_list2 - temp_array #array([ 5, 3, 1, -1, -3, -5])
temp_list2 / temp_array #array([6. , 2.5 , 1.33333333, 0.75 , 0.4 ,
# 0.16666667])
#數(shù)組*標(biāo)量
temp_array2 * 3 # 返回值 array([18, 15, 12, 9, 6, 3])
# 多維數(shù)組
temp_array3 = np.eye(6)
temp_array3*3
# array([[3., 0., 0., 0., 0., 0.],
# [0., 3., 0., 0., 0., 0.],
# [0., 0., 3., 0., 0., 0.],
# [0., 0., 0., 3., 0., 0.],
# [0., 0., 0., 0., 3., 0.],
# [0., 0., 0., 0., 0., 3.]])
temp_array * temp_array3
# array([[1., 0., 0., 0., 0., 0.],
# [0., 2., 0., 0., 0., 0.],
# [0., 0., 3., 0., 0., 0.],
# [0., 0., 0., 4., 0., 0.],
# [0., 0., 0., 0., 5., 0.],
# [0., 0., 0., 0., 0., 6.]])
temp_array3 * temp_array
# array([[1., 0., 0., 0., 0., 0.],
# [0., 2., 0., 0., 0., 0.],
# [0., 0., 3., 0., 0., 0.],
# [0., 0., 0., 4., 0., 0.],
# [0., 0., 0., 0., 5., 0.],
# [0., 0., 0., 0., 0., 6.]])
temp_array3 / temp_array
# array([[1., 0., 0. , 0., 0. ,0.],
#
# [0. , 0.5 , 0. , 0. , 0. , 0. ],
# [0. , 0. , 0.33333333, 0. , 0. , 0. ],
# [0. , 0. , 0. , 0.25 , 0. , 0. ],
# [0. , 0. , 0. , 0. , 0.2 , 0. ],
# [0. , 0. , 0. , 0. , 0. , 0.16666667]])
temp_array3 - temp_array
# array([[ 0., -2., -3., -4., -5., -6.],
# [-1., -1., -3., -4., -5., -6.],
# [-1., -2., -2., -4., -5., -6.],
# [-1., -2., -3., -3., -5., -6.],
# [-1., -2., -3., -4., -4., -6.],
# [-1., -2., -3., -4., -5., -5.]])
temp_array3 + temp_array
# array([[2., 2., 3., 4., 5., 6.],
# [1., 3., 3., 4., 5., 6.],
# [1., 2., 4., 4., 5., 6.],
# [1., 2., 3., 5., 5., 6.],
# [1., 2., 3., 4., 6., 6.],
# [1., 2., 3., 4., 5., 7.]])
temp_array + temp_array3
# array([[2., 2., 3., 4., 5., 6.],
# [1., 3., 3., 4., 5., 6.],
# [1., 2., 4., 4., 5., 6.],
# [1., 2., 3., 5., 5., 6.],
# [1., 2., 3., 4., 6., 6.],
# [1., 2., 3., 4., 5., 7.]])
# (2,3) * (3,2) 的類型 numpy中無(wú)法進(jìn)行操作,矩陣中可以進(jìn)行運(yùn)算
temp_list5 = [[1,2,3],[3,4,5]]
temp_array5 = np.array(temp_list5) # temp_array5 的形狀 (2, 3)
temp_list6 = [[1,2],[3,4],[5,6]]
temp_array6 = np.array(temp_list6) # temp_array6 的形狀(3, 2)
temp_array5 * temp_array6 # 報(bào)錯(cuò) ValueError: operands could not be broadcast together with shapes (2,3) (3,2)
# 注: 不同大小的數(shù)組之間的運(yùn)算叫作廣播,稍后介紹。