日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

利用python进行数据分析_从删库到跑路

發(fā)布時間:2024/3/7 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 利用python进行数据分析_从删库到跑路 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

目錄

前言

一 numpy模塊

1.numpy的數(shù)據(jù)結(jié)構(gòu):多維數(shù)組ndarray

數(shù)組轉(zhuǎn)置和軸對換

矩陣內(nèi)積

通用函數(shù)

利用數(shù)組進(jìn)行數(shù)據(jù)處理(矢量化)

將條件邏輯表述為數(shù)組運(yùn)算

數(shù)組和統(tǒng)計法方法?

約簡

排序sort

唯一化和其他集合邏輯

數(shù)組中的集合運(yùn)算

用于數(shù)組的文件輸入輸出

線性代數(shù)

隨機(jī)數(shù)生成

部分numpy.random函數(shù)

隨即漫步

數(shù)組重塑

扁平化或散開

C和Fortran順序

數(shù)組的合并與拆分

元素的重復(fù)操作:tile和repeat

花式索引的等價函數(shù):take和put

廣播

三維數(shù)組的廣播

ufunc高級應(yīng)用

自定義ufunc

結(jié)構(gòu)化和記錄式數(shù)組

嵌套dtype和多維字段

排序

間接排序:argsort和lexsort

在有序數(shù)組中查找元素:searchsorted方法和digitize函數(shù)

numpy的matrix類

內(nèi)存映像文件

性能建議

Cpython和numpy

二 pandas模塊

1.pandas的數(shù)據(jù)結(jié)構(gòu):Series和DataFrame

三 matplotlib模塊

四? ? scipy模塊


?

@python3.6.6;ubuntu18.04

前言

常用模塊為numpy、pandas、matplotlib、scipy

代碼編寫工具:jupyter

一 numpy模塊

1.numpy的數(shù)據(jù)結(jié)構(gòu):多維數(shù)組ndarray

Numpy最重要的一個特點(diǎn)就是其N維數(shù)組對象ndarray,ndarray是一個通用的同構(gòu)數(shù)據(jù)多維容器,也就是說其中所有的元組必須是相同類型的,他接收一切序列類型的對象(包括其他數(shù)組)。Numpy的ndarray提供了一種將同質(zhì)數(shù)據(jù)塊(可以是連續(xù)或非連續(xù)存儲的)解釋為多維數(shù)組對象的方式,數(shù)據(jù)類型dtype決定了數(shù)據(jù)的解釋方式,比如浮點(diǎn)數(shù)、整數(shù)、布爾值等

ndarray如此強(qiáng)大的原因部分是因?yàn)樗袛?shù)組對象都是數(shù)據(jù)塊的一個跨度視圖(strided view),ndarray不只是一塊內(nèi)存和一個dtype,它還有跨度信息,這使得數(shù)組能以各種步幅(step size)在內(nèi)存中移動,更準(zhǔn)確的說,ndarray由以下內(nèi)容組成:

一個指向數(shù)組(一個系統(tǒng)內(nèi)存塊)的指針

一個表示數(shù)組形狀(shape)的元組,如3*3的數(shù)組形狀元組為(3,3)

一個跨度元組(stride),其中整數(shù)指的是為了前進(jìn)到當(dāng)前緯度下一個元素需要跨過的字節(jié)數(shù),如3*4*5的foalt64數(shù)組,其跨度為(160,40,8)

下圖簡單地說明了ndarray的內(nèi)部結(jié)構(gòu)

1.0 ndarray的數(shù)據(jù)類型(dtype)體系

你可能需要檢查數(shù)組中所包含的數(shù)據(jù)是否是整數(shù)、浮點(diǎn)數(shù)、字符串或python對象,因?yàn)楦↑c(diǎn)數(shù)的種類很多,判斷dtype是否屬于某個大類的工作非常繁瑣,但是,dtype都有一個超類(比如np.interger和np.floating),他們可以和np.issubdtype函數(shù)結(jié)合,調(diào)用dtype的mro方法即可查看dtype的所有父類(有些數(shù)據(jù)類型后面帶有下劃線,是為了和python的數(shù)據(jù)類型區(qū)別開來)

In [9]: ints=np.ones(10,dtype=np.uint16)In [10]: floats=np.ones(10,dtype=np.float32)In [11]: np.issubdtype(ints.dtype,np.integer)#判斷數(shù)據(jù)類型,同python的isinstance Out[11]: TrueIn [12]: np.issubdtype(floats.dtype,np.floating) Out[12]: True#調(diào)用dtype的mro方法即可查看其所有的父類In [13]: np.float64.mro() Out[13]: [numpy.float64,numpy.floating,numpy.inexact,numpy.number,numpy.generic,float,object]

下圖簡單說明了dtype體系以及父子類關(guān)系

1.1 創(chuàng)建數(shù)組

import numpy as np In [15]: np.array([1,2,3]) Out[15]: array([1, 2, 3])#傳入列表,產(chǎn)生一維數(shù)組In [16]: np.array([[1,2,3],[4,5,6]]) Out[16]: array([[1, 2, 3],[4, 5, 6]])#傳入嵌套列表,產(chǎn)生二維數(shù)組#傳入一個數(shù)組 In [22]: rnd=np.random.randn(12)In [23]: rnd_re=rnd.reshape(3,4)#reshape,重新構(gòu)造數(shù)組結(jié)構(gòu)In [24]: rnd Out[24]: array([ 0.65986137, 0.59780991, -0.29968381, -0.13900897, -0.91233434,-1.11650251, 0.10361076, -0.99113903, -0.18876077, -1.07867959,-1.35017413, -0.02826018])In [25]: rnd_re Out[25]: array([[ 0.65986137, 0.59780991, -0.29968381, -0.13900897],[-0.91233434, -1.11650251, 0.10361076, -0.99113903],[-0.18876077, -1.07867959, -1.35017413, -0.02826018]])In [26]: np.array(rnd_re) Out[26]: array([[ 0.65986137, 0.59780991, -0.29968381, -0.13900897],[-0.91233434, -1.11650251, 0.10361076, -0.99113903],[-0.18876077, -1.07867959, -1.35017413, -0.02826018]])

1.2 shape和dtype

shape表示各維度大小的元組,tdype用于說明數(shù)組數(shù)據(jù)類型的對象

In [1]: import numpy as npIn [2]: data=np.array([1,2,3])In [3]: data.shape Out[3]: (3,)In [4]: data=np.array([[1,2,3],[4,5,6]])In [5]: data.shape Out[5]: (2, 3)In [6]: data.dtype Out[6]: dtype('int64')

1.3 empty、zeros、ones

empty創(chuàng)建一個沒有任何具體值的數(shù)組(應(yīng)該是無意義的虛數(shù))

zeros創(chuàng)建一個全是0的數(shù)組

ones創(chuàng)建一個全是1的數(shù)組

In [30]: np.empty((3,3)) Out[30]: array([[1.96923895e-316, 2.04482388e-316, 3.92581470e+170],[2.33607195e-301, 5.94613337e-302, 2.29457644e+156],[3.66137200e-244, 4.10074486e-322, 3.95252517e-322]])In [32]: np.zeros((3,3)) Out[32]: array([[0., 0., 0.],[0., 0., 0.],[0., 0., 0.]])In [33]: np.ones((3,3)) Out[33]: array([[1., 1., 1.],[1., 1., 1.],[1., 1., 1.]])

1.4 arange

arange是python內(nèi)置函數(shù)range的數(shù)組版

In [34]: np.arange(10) Out[34]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

1.5 ndarray的數(shù)據(jù)類型

dtype(數(shù)據(jù)類型)是一個特殊對象,它含有ndarray將一塊內(nèi)存解釋為特定數(shù)據(jù)類型所需的信息

主要有int64,int32,float64,float32等(不涉及底層工作,很少涉及,不用記)

#數(shù)值型dtype的命名方式相同:一個類型名(如int,float),后面跟一個表示各元素位長的數(shù)字,如float64 In [36]: np.array([1,2,3]).dtype Out[36]: dtype('int64')In [37]: data=np.array([1,2,3],dtype=np.float64)In [38]: data.dtype Out[38]: dtype('float64')

1.6 astype

通過astype可以顯式的轉(zhuǎn)換數(shù)組的數(shù)據(jù)類型

In [41]: data=np.array(['1','2','3'])In [42]: data.dtype Out[42]: dtype('<U1')In [43]: data.astype(np.float64)#注意:使用astype會創(chuàng)建出一個新的數(shù)組(即不改變原始數(shù)據(jù)) Out[43]: array([1., 2., 3.])#astype也可用作調(diào)用其他數(shù)組的數(shù)據(jù)類型 In [44]: data1=np.array([1,2,3])In [45]: data2=np.array(['1','2','3'])In [46]: data2.astype(data1.dtype) Out[46]: array([1, 2, 3])

1.7 數(shù)組和標(biāo)量的運(yùn)算

矢量化(vectorization),數(shù)組可以讓你不是用循環(huán)即可對數(shù)據(jù)執(zhí)行批量運(yùn)算,這通常叫做矢量化

數(shù)組和標(biāo)量之間的運(yùn)算,會將運(yùn)算應(yīng)用到元素級,同樣的,大小相等的數(shù)組之間的任何運(yùn)算都會應(yīng)用到元素級

廣播:不同大小數(shù)組之間的運(yùn)算叫做廣播

In [47]: data=np.array([[1,2,3],[4,5,6]])In [49]: data*data Out[49]: array([[ 1, 4, 9],[16, 25, 36]])In [52]: data*3 Out[52]: array([[ 3, 6, 9],[12, 15, 18]])

1.8索引和切片

一維數(shù)組很簡單,類似python數(shù)據(jù)類型

In [53]: data=np.array([1,2,3])In [54]: data[1] Out[54]: 2

當(dāng)你將一個標(biāo)量值賦值給一個切片時,該值會自動傳播到整個選區(qū),跟列表最重要的區(qū)別在于,數(shù)組切片是原始數(shù)據(jù)的視圖,即和數(shù)據(jù)不會被復(fù)制,視圖上的任何修改都會直接反映到源數(shù)據(jù),若需要得到數(shù)組的副本,需要使用data.copy()顯式的復(fù)制

In [59]: data_arr=np.array([x for x in range(10)])In [61]: arr_slice=data_arr[5:8]In [62]: data_arr Out[62]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])In [64]: arr_slice Out[64]: array([5, 6, 7])In [65]: arr_slice[1]=12345In [66]: arr_slice Out[66]: array([ 5, 12345, 7])In [67]: data_arr Out[67]: array([ 0, 1, 2, 3, 4, 5, 12345, 7, 8,9]) #給數(shù)組arr_slice賦值,會改變其源數(shù)據(jù)data_arr,而列表則不會 In [68]: data_list=[x for x in range(10)]In [69]: list_slice=data_list[5:8]In [70]: data_list Out[70]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]In [71]: list_slice Out[71]: [5, 6, 7]In [72]: list_slice[1]=12345In [73]: list_slice Out[73]: [5, 12345, 7]In [74]: data_list Out[74]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] #使用copy()方法顯式的復(fù)制源數(shù)據(jù),則不會修改源數(shù)據(jù) In [75]: data_arr=np.array([x for x in range(10)])In [76]: data_arr Out[76]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])In [77]: arr_slice=data_arr[5:8].copy()In [78]: arr_slice Out[78]: array([5, 6, 7])In [79]: arr_slice=12345In [80]: arr_slice Out[80]: 12345In [81]: data_arr Out[81]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

二維數(shù)組中,索引位置上的元素不再是標(biāo)量,而是一維數(shù)組,因此對各個元素進(jìn)行遞歸訪問需要的方法不同,其切片有兩種方法實(shí)現(xiàn),其中第一種類似嵌套列表的切片

In [84]: data_arr=np.array([[x for x in range(10)],[x for x in range(10,20)]])In [85]: data_arr Out[85]: array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9],[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]])In [86]: data_arr[1][1] Out[86]: 11In [87]: data_arr[1,1] Out[87]: 11

三維數(shù)組,切片取值可以理解為三層嵌套列表,同樣可以使用兩種方法表達(dá)

In [90]: data_arr=np.array([[[x for x in range(10)],[x for x in range(10,20)]],[...: [x for x in range(20,30)],[x for x in range(40,50)]]])In [91]: data_arr Out[91]: 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, 24, 25, 26, 27, 28, 29],[40, 41, 42, 43, 44, 45, 46, 47, 48, 49]]])In [95]: data_arr[1,1,1] Out[95]: 41In [92]: data_arr[1] Out[92]: array([[20, 21, 22, 23, 24, 25, 26, 27, 28, 29],[40, 41, 42, 43, 44, 45, 46, 47, 48, 49]])In [93]: data_arr[1][1] Out[93]: array([40, 41, 42, 43, 44, 45, 46, 47, 48, 49])In [94]: data_arr[1][1][1] Out[94]: 41

布爾型索引

跟算術(shù)運(yùn)算一樣,數(shù)組的比較運(yùn)算(如==)也是矢量花的,因此,對數(shù)據(jù)和字符串的比較運(yùn)算將會產(chǎn)生一個布爾型數(shù)組,布爾型數(shù)組的軸長度跟被索引的數(shù)組的軸長度一致

In [105]: data=np.array(['a','b','c'])In [106]: data=='d' Out[106]: array([False, False, False])In [107]: data!='d' Out[107]: array([ True, True, True])

布爾型數(shù)組和整數(shù)數(shù)組混合使用

In [108]: data1=np.array(['a','b','c'])In [109]: data2=np.array([1,2,3])In [110]: data_boolean=data1=='a'In [111]: data_boolean Out[111]: array([ True, False, False])In [112]: data2[data_boolean] Out[112]: array([1])

布爾算術(shù)運(yùn)算符:& |

python中的and和or在numpy中無效

In [108]: data1=np.array(['a','b','c']) In [109]: data2=np.array([1,2,3])In [121]: data_boolean=(data1=='a')&(data1=='b')In [122]: data_boolean Out[122]: array([False, False, False])In [123]: data_boolean=(data1=='a')|(data1=='b')In [124]: data_boolean Out[124]: array([ True, True, False])In [125]: data2[data_boolean] Out[125]: array([1, 2])

花式索引

花式索引(Fancy indexing)是一個Numpy術(shù)語,它指利用整數(shù)數(shù)組進(jìn)行索引

#子集賦值 In [126]: arr=np.empty((8,4))In [127]: arr Out[127]: array([[1.78873028e-316, 6.92799192e-310, 6.92799191e-310,6.92799192e-310],[6.92799191e-310, 6.92799191e-310, 6.92799191e-310,6.92799191e-310],[6.92799191e-310, 6.92799191e-310, 6.92799192e-310,6.92799191e-310],[6.92799192e-310, 6.92799191e-310, 6.92799191e-310,6.92799192e-310],[6.92799191e-310, 6.92799191e-310, 6.92799192e-310,6.92799192e-310],[6.92799191e-310, 6.92799191e-310, 5.41734680e-317,6.92799191e-310],[6.92799191e-310, 6.92799191e-310, 6.92799191e-310,6.92799191e-310],[6.92799192e-310, 6.92799192e-310, 6.92799192e-310,6.92799191e-310]])In [128]: for i in range(8):...: arr[i]=i...: In [129]: arr Out[129]: array([[0., 0., 0., 0.],[1., 1., 1., 1.],[2., 2., 2., 2.],[3., 3., 3., 3.],[4., 4., 4., 4.],[5., 5., 5., 5.],[6., 6., 6., 6.],[7., 7., 7., 7.]])#為了以特定的順序選取子集,只需要傳入一個用于指定順序的整數(shù)列表或ndarray即可 In [130]: arr[[4,3,0,6]] Out[130]: array([[4., 4., 4., 4.],[3., 3., 3., 3.],[0., 0., 0., 0.],[6., 6., 6., 6.]]) #一次傳入多個索引數(shù)組會有一點(diǎn)特別,他返回一個一維數(shù)組,其中的元素對應(yīng)各個索引元組In [133]: arr[[1,2,3,4],[5,6,7,0]]#第二個列表表示列的排序,不能超過3 --------------------------------------------------------------------------- IndexError Traceback (most recent call last) <ipython-input-133-b97868d57f0c> in <module>() ----> 1 arr[[1,2,3,4],[5,6,7,0]]IndexError: index 5 is out of bounds for axis 1 with size 4In [134]: arr[[1,4,5,7],[0,3,1,2]]#返回的是數(shù)組的第一列數(shù)據(jù),即默認(rèn)的索引 Out[134]: array([1., 4., 5., 7.])In [143]: arr[[1,4,5,7]][:,[0,3,1,2]]#前面的列表表示子集,后面列表表示選取的子集的數(shù)據(jù)排列 Out[143]: array([[ 4, 7, 5, 6],[16, 19, 17, 18],[20, 23, 21, 22],[28, 31, 29, 30]])#也可以使用np.ix_函數(shù),它可以將兩個一維整數(shù)數(shù)組轉(zhuǎn)換為一個用于選取方形區(qū)域的索引 In [144]: arr[np.ix_([1,4,5,7],[0,3,1,2])] Out[144]: array([[ 4, 7, 5, 6],[16, 19, 17, 18],[20, 23, 21, 22],[28, 31, 29, 30]])

數(shù)組轉(zhuǎn)置和軸對換

transpose和T

簡單轉(zhuǎn)置用T,復(fù)雜用transpose

數(shù)組轉(zhuǎn)置是重塑的一種特殊形式,它返回的是源數(shù)據(jù)的視圖(不會進(jìn)行任何復(fù)制),數(shù)組不僅有transpose方法,還有一個T屬性

In [5]: data=np.arange(12).reshape((3,4))In [6]: data Out[6]: array([[ 0, 1, 2, 3],[ 4, 5, 6, 7],[ 8, 9, 10, 11]])In [7]: data.T Out[7]: array([[ 0, 4, 8],[ 1, 5, 9],[ 2, 6, 10],[ 3, 7, 11]])

對于高維數(shù)組,transpose需要得到一個由軸編號組成的元組,才能對數(shù)組進(jìn)行轉(zhuǎn)置

array([[[ 0, 1, 2, 3],[ 4, 5, 6, 7]],[[ 8, 9, 10, 11],[12, 13, 14, 15]]])In [12]: arr.transpose((1,0,2))#軸1和軸0互換,軸2不變,原本的順序是(0,1,2),分別表示總共有三個軸 Out[12]: array([[[ 0, 1, 2, 3],[ 8, 9, 10, 11]],[[ 4, 5, 6, 7],[12, 13, 14, 15]]])

矩陣內(nèi)積

np.dot

In [9]: np.dot(data,data.T) Out[9]: array([[ 14, 38, 62],[ 38, 126, 214],[ 62, 214, 366]])

通用函數(shù)

即(ufunc)既是一種ndarray中的數(shù)據(jù)執(zhí)行元素級運(yùn)算的函數(shù),你可以將其看作簡單函數(shù)的矢量花包裝器

簡單函數(shù)是指:接受一個或多個標(biāo)量值,產(chǎn)生一個或多個標(biāo)量值

sqrt和exp

接收一個變量的ufunc稱為一元ufunc,其他如add和maximum稱為二元ufunc

In [19]: arr=np.arange(10)In [20]: np.sqrt(arr)#平方根 Out[20]: array([0. , 1. , 1.41421356, 1.73205081, 2. ,2.23606798, 2.44948974, 2.64575131, 2.82842712, 3. ])In [21]: np.exp(arr)#以自然常數(shù)e為底數(shù)的指數(shù)函數(shù),e是一個2.71828....的常數(shù) Out[21]: 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, 8.10308393e+03])

add和maximum

In [22]: arr1=np.array([1,2,3])In [23]: arr2=np.array([4,5,6])In [24]: np.add(arr1,arr2)#數(shù)組1和數(shù)組2相加 Out[24]: array([5, 7, 9])In [29]: arr1=np.array([1,3,5])In [30]: arr2=np.array([1,2,6])In [31]: np.maximum(arr1,arr2)#取數(shù)組1和數(shù)組2對應(yīng)元素的最大值,組成新數(shù)組 Out[31]: array([1, 3, 6])

以下表格是一些常見的通用函數(shù)

一元ufunc?
abs、fabs計算整數(shù)、浮點(diǎn)數(shù)和復(fù)數(shù)的絕對值,非復(fù)數(shù),使用fabs更快
sqrt計算各元素的平方根,相當(dāng)于arr**0.5
square計算各元素的平方,相當(dāng)于arr**2
exp計算各元素指數(shù)e
log,log10,log2,log1p分別為自然對數(shù)(底數(shù)為e),底數(shù)為10的對數(shù),底數(shù)為2的對數(shù),log(1+x)
sign計算各元素的正負(fù)號,正為1,0為零,負(fù)為-1
ceil計算各元素的ceiling值,即大于等于該值的最小整數(shù)
floor計算各元素的floor值,即小于等于該值的最小整數(shù)
rint將各元素四舍五入到最接近的整數(shù)
modf將數(shù)組的元素的整數(shù)和小數(shù)部分以兩個獨(dú)立的數(shù)組返回
isnan返回一個哪些值是控制NaN的布爾型數(shù)組
isfinite,isinf是否是有窮(finite),是否是無窮的(isinf),返回一個布爾型數(shù)組
cos,cosh,sin,sinh,tan,tanh普通型和雙曲型三角函數(shù)
arccos,arccosh,arcsin,arcsinh,arctan,arctanh反三角函數(shù)
logical_not計算各元素not x的真值,相當(dāng)于-arr
二元ufunc?
add將數(shù)組中對應(yīng)元素相加
subtract將數(shù)組中對應(yīng)元素相減
multiply數(shù)組元素相乘
divide,floor_divide除法,向下整除(去掉余數(shù))
power對第一個數(shù)組中的元素A,根據(jù)第二個數(shù)組中的元素B,計算A的B次方
maximum,fmax元素級的最大值計算,fmax忽略NaN值
minimum,fimin元素級的最小值計算,fmin忽略NaN值
mod元素級的求模運(yùn)算(除法的余數(shù))
copysign將第二個數(shù)組的值的符號復(fù)制給第一個數(shù)組中的值
greater,greater_equal,less,less_equal,equal,not_equal元素級比較運(yùn)算,最終產(chǎn)生布爾型數(shù)組
logical_and,logical_or,logical_xor

元素級邏輯運(yùn)算,與或非,相當(dāng)于&、|、^

??
??
??

利用數(shù)組進(jìn)行數(shù)據(jù)處理(矢量化)

Numpy數(shù)組使多種數(shù)據(jù)處理任務(wù)可以簡單表述為數(shù)組表達(dá)式(否則需要寫循環(huán))

用數(shù)組表達(dá)式替代循環(huán)的做法,通常稱作矢量化。

一般來說數(shù)組化運(yùn)算要比純python的等價運(yùn)算要快上一兩各數(shù)量級,尤其是各種數(shù)值運(yùn)算

作為簡單的例子,假設(shè)我們想要在一組值(網(wǎng)格型)上計算函數(shù)sqrt(x^2+y^2)。np.meshgrid函數(shù)接受兩個一維數(shù)組,并產(chǎn)生兩個二維矩陣(對應(yīng)于兩個數(shù)組中所有的(x,y)對):

In [48]: points=np.arange(-5,5,0.01)In [49]: x,y=np.meshgrid(points,points)In [50]: x Out[50]: array([[-5. , -4.99, -4.98, ..., 4.97, 4.98, 4.99],[-5. , -4.99, -4.98, ..., 4.97, 4.98, 4.99],[-5. , -4.99, -4.98, ..., 4.97, 4.98, 4.99],...,[-5. , -4.99, -4.98, ..., 4.97, 4.98, 4.99],[-5. , -4.99, -4.98, ..., 4.97, 4.98, 4.99],[-5. , -4.99, -4.98, ..., 4.97, 4.98, 4.99]])In [51]: y Out[51]: array([[-5. , -5. , -5. , ..., -5. , -5. , -5. ],[-4.99, -4.99, -4.99, ..., -4.99, -4.99, -4.99],[-4.98, -4.98, -4.98, ..., -4.98, -4.98, -4.98],...,[ 4.97, 4.97, 4.97, ..., 4.97, 4.97, 4.97],[ 4.98, 4.98, 4.98, ..., 4.98, 4.98, 4.98],[ 4.99, 4.99, 4.99, ..., 4.99, 4.99, 4.99]])In [53]: z=np.sqrt(x**2+y**2)In [54]: z Out[54]: array([[7.07106781, 7.06400028, 7.05693985, ..., 7.04988652, 7.05693985,7.06400028],[7.06400028, 7.05692568, 7.04985815, ..., 7.04279774, 7.04985815,7.05692568],[7.05693985, 7.04985815, 7.04278354, ..., 7.03571603, 7.04278354,7.04985815],...,[7.04988652, 7.04279774, 7.03571603, ..., 7.0286414 , 7.03571603,7.04279774],[7.05693985, 7.04985815, 7.04278354, ..., 7.03571603, 7.04278354,7.04985815],[7.06400028, 7.05692568, 7.04985815, ..., 7.04279774, 7.04985815,7.05692568]])

將條件邏輯表述為數(shù)組運(yùn)算

np.where

np.where函數(shù)是三元表達(dá)式x if condition else y的矢量化版本。假設(shè)我們有一個布爾數(shù)組和兩個值數(shù)組

np.where的第二個和第三個參數(shù)不必是數(shù)組,它們都可以是標(biāo)量值。在數(shù)據(jù)分析工作中,where通常用于根據(jù)另一個數(shù)組而產(chǎn)生一個新的數(shù)組。

In [56]: arr1=np.array([1,2,3,4,5])In [57]: arr2=np.array([-1,-2,-3,-4,-5])In [58]: arr3=np.array([True,False,True,False,True])In [62]: arr=np.array([x if z else y for x,y,z in zip(arr1,arr2,arr3)])In [63]: arr Out[63]: array([ 1, -2, 3, -4, 5])In [64]: arr=np.array(np.where(arr3,arr1,arr2))#np.where返回的是數(shù)組In [65]: arr Out[65]: array([ 1, -2, 3, -4, 5])#將np.where用于替換值,如將數(shù)組的負(fù)數(shù)改為2:In [67]: arr=np.random.randn(10)In [68]: arr Out[68]: array([-0.43310012, -0.78072221, 0.05956466, 0.07686748, -0.29438555,-0.53863612, 0.96500903, -1.40994316, -1.03975959, 1.83357067])In [69]: arr_new=np.where(arr<0,2,arr)In [70]: arr_new Out[70]: array([2. , 2. , 0.05956466, 0.07686748, 2. ,2. , 0.96500903, 2. , 2. , 1.83357067])

數(shù)學(xué)和統(tǒng)計方法?

約簡

通過數(shù)組上的一組數(shù)學(xué)函數(shù)對整個數(shù)組或者某條軸上的數(shù)據(jù)進(jìn)行統(tǒng)計計算,如求和sum、平均值mean以及標(biāo)準(zhǔn)差std等聚合計算(aggregation,通常叫做約簡(reduction))既可以當(dāng)做數(shù)組的實(shí)例方法調(diào)用,也可以當(dāng)做頂級Numpy函數(shù)使用

In [4]: arr=np.random.randn(5)#正態(tài)分布的隨即數(shù)據(jù)In [5]: arr Out[5]: array([-0.11860027, 1.05271905, 0.57255691, -0.49385782, 0.37800909])In [6]: arr.sum() Out[6]: 1.3908269625978642In [7]: np.sum(arr) Out[7]: 1.3908269625978642

mean和sum

這類函數(shù)可以接受一個axis參數(shù),用于計算該軸向上的統(tǒng)計值,最終返回一個少一維的數(shù)組

In [9]: arr=np.arange(20).reshape(5,4)In [10]: arr Out[10]: array([[ 0, 1, 2, 3],[ 4, 5, 6, 7],[ 8, 9, 10, 11],[12, 13, 14, 15],[16, 17, 18, 19]])In [14]: arr.sum()#全部元素 Out[14]: 190In [15]: arr.sum(0)#在數(shù)組上一個列表表示一列,axis=0表示的是行,計算的是所有列表每個索引上的和 Out[15]: array([40, 45, 50, 55])In [16]: arr.sum(1)#數(shù)組上一個列表表示一列,axis=1表示的是列,計算的一個列表的和 Out[16]: array([ 6, 22, 38, 54, 70])

cumsum和cumprod

累計和,累計積這類方法則不聚合,而是產(chǎn)生一個由中間結(jié)果組成的數(shù)組

In [17]: arr Out[17]: array([[ 0, 1, 2, 3],[ 4, 5, 6, 7],[ 8, 9, 10, 11],[12, 13, 14, 15],[16, 17, 18, 19]])In [18]: arr.cumsum(axis=1)#列表內(nèi)的累計和 Out[18]: array([[ 0, 1, 3, 6],[ 4, 9, 15, 22],[ 8, 17, 27, 38],[12, 25, 39, 54],[16, 33, 51, 70]])In [19]: arr.cumprod(axis=1)#列表內(nèi)的累計積 Out[19]: array([[ 0, 0, 0, 0],[ 4, 20, 120, 840],[ 8, 72, 720, 7920],[ 12, 156, 2184, 32760],[ 16, 272, 4896, 93024]])

基本數(shù)組統(tǒng)計方法

sum全部或某軸向的元素求和,零長度的數(shù)組的sum為0
mean全部或某軸向的元素平均值,零長度的數(shù)組的mean為NaN
std、var

分別為標(biāo)準(zhǔn)差和方差,自由度可調(diào)(默認(rèn)為n)

min、max全部或某軸向上的最大值和最小值
argmin、argmax全部或某軸向上的最大最小值的索引
cumsum全部或某軸向上的累計和
cumprod全部或某軸向上的累計積

用于布爾型數(shù)組的方法

在使用統(tǒng)計方法時,布爾值會強(qiáng)制轉(zhuǎn)換為1(True)和0(Flase),因此sum經(jīng)常被用來對布爾型數(shù)組中True值的計數(shù)

In [28]: arr=np.random.randn(100)In [29]: (arr>0).sum() Out[29]: 52

any和all

any用于判斷存在一個或多個,all用于判斷全部都是

In [28]: arr=np.random.randn(100)In [30]: (arr>0).any() Out[30]: TrueIn [31]: (arr>0).all() Out[31]: False

排序sort

arr.sort和np.sort

通過arr.sort方法就地排序(直接改變源數(shù)據(jù)),np.sort()返回的是數(shù)組的已排序副本(即不修改源數(shù)據(jù)),可以對全部元素或者某軸向上的元素進(jìn)行排序

In [46]: arr=np.random.randn(12).reshape(4,3)In [47]: arr Out[47]: array([[ 5.82831352e-02, -7.74374388e-01, 1.47850625e+00],[ 8.30603959e-01, -5.74236357e-01, -4.13521434e-01],[ 8.70914589e-04, -5.46720474e-01, -5.41121958e-01],[-7.03866197e-01, 1.95273830e+00, -5.85538385e-01]])In [48]: arr.sort()#默認(rèn)axis=1,在列上排序In [49]: arr Out[49]: array([[-7.74374388e-01, 5.82831352e-02, 1.47850625e+00],[-5.74236357e-01, -4.13521434e-01, 8.30603959e-01],[-5.46720474e-01, -5.41121958e-01, 8.70914589e-04],[-7.03866197e-01, -5.85538385e-01, 1.95273830e+00]])In [50]: arr.sort(0)#行上排序,會改變列表的值In [51]: arr Out[51]: array([[-7.74374388e-01, -5.85538385e-01, 8.70914589e-04],[-7.03866197e-01, -5.41121958e-01, 8.30603959e-01],[-5.74236357e-01, -4.13521434e-01, 1.47850625e+00],[-5.46720474e-01, 5.82831352e-02, 1.95273830e+00]])

np.sort(arr)

In [52]: arr=np.random.randn(12).reshape(4,3)In [53]: arr Out[53]: array([[-1.0651435 , -0.70624382, 0.05124272],[ 0.69190929, 1.03548097, 0.64937742],[ 1.54626701, -0.08302486, 0.39043255],[-1.03014956, -0.12934306, 1.47813622]])In [54]: np.sort(arr) Out[54]: array([[-1.0651435 , -0.70624382, 0.05124272],[ 0.64937742, 0.69190929, 1.03548097],[-0.08302486, 0.39043255, 1.54626701],[-1.03014956, -0.12934306, 1.47813622]])In [55]: arr Out[55]: array([[-1.0651435 , -0.70624382, 0.05124272],[ 0.69190929, 1.03548097, 0.64937742],[ 1.54626701, -0.08302486, 0.39043255],[-1.03014956, -0.12934306, 1.47813622]])

唯一化和其他集合邏輯

np.unique

numpy提供了一些針對一維ndarray的基本集合運(yùn)算,最常用的時np.unique,它用于找出數(shù)組中的唯一值并返回已排序的結(jié)果

In [61]: arr=np.array([1,1,2,3,4,5,2,3,4,5,6])In [62]: np.unique(arr) Out[62]: array([1, 2, 3, 4, 5, 6])

np.in1d

用于測試一個數(shù)組中的值在另一個數(shù)組中的成員資格,返回一個布爾型數(shù)組,第一個參數(shù)為源數(shù)據(jù),驗(yàn)證第二個參數(shù)在源數(shù)據(jù)中的成員資格

In [68]: arr1=np.array([1,2,3,4,5])In [69]: arr2=np.array([1,2,3,4,5,6])In [70]: np.in1d(arr1,arr2) Out[70]: array([ True, True, True, True, True])In [71]: np.in1d(arr1,[1,2...: ]) Out[71]: array([ True, True, False, False, False])

數(shù)組中的集合運(yùn)算

unique()計算x中的唯一元素(去重),并返回有序結(jié)果
intersect1d(x,y)計算x,y的公共元素,并返回有序結(jié)果
union1d(x,y)

計算x,y的并集,并返回有序結(jié)果

in1d(x,y)得到一個表示'y元素是否在x中'的布爾型數(shù)組,數(shù)組長度等于x
setdiff1d(x,y)集合的差,即元素在x中且不在y中
setxor1d(x,y)集合的對稱差,即存在于一個數(shù)組中,但不同時存在于兩個數(shù)組中的元素,即'異或'

用于數(shù)組的文件輸入輸出

np.load和np.save, 用于讀寫磁盤數(shù)組數(shù)據(jù),默認(rèn)情況下,數(shù)組是以未壓縮的原始二進(jìn)制格式保存在擴(kuò)展名為.npy的文件中的

如果save的文件路徑末尾沒有擴(kuò)展名.npy,則該擴(kuò)展名會被自動加速,通過np.load讀取磁盤數(shù)據(jù)時需要加入后綴名

In [72]: arr=np.arange(10)In [73]: np.save('save_arr',arr) In [75]: np.load('save_arr.npy') Out[75]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

np.savez

將多個數(shù)組保存到一個壓縮文件中,將數(shù)組以關(guān)鍵字參數(shù)的形式傳入即可,后綴名為.npz的文件,

加載.npz文件時,你會得到一個類似字典的對象,該對象會對各個數(shù)組進(jìn)行延遲加載:

In [77]: np.savez('savez_arr',aaa=np.array([12,34]),bbb=np.array([3,4,2,2]))In [79]: np.load('savez_arr.npz') Out[79]: <numpy.lib.npyio.NpzFile at 0x7f321c1c7c50>In [80]: ar=np.load('savez_arr.npz')In [81]: ar['aaa'] Out[81]: array([12, 34])

np.loadtxt和np.genformtxt

將普通數(shù)據(jù)加載到普通的numpy的數(shù)組中,可以指定各種分隔符、針對特定列的轉(zhuǎn)換器函數(shù)、需要跳國的行數(shù)等

zelin@2018:~$ cat nppp.txt 1,1,1,1,1,1,1 2,2,2,2,2,2,2 3,3,3,3,3,3,3In [86]: np.loadtxt('nppp.txt',delimiter=',')#必須指定分隔符 Out[86]: array([[1., 1., 1., 1., 1., 1., 1.],[2., 2., 2., 2., 2., 2., 2.],[3., 3., 3., 3., 3., 3., 3.]])In [88]: np.genfromtxt('nppp.txt')#面向的時結(jié)構(gòu)化數(shù)組和缺失數(shù)據(jù)處理 Out[88]: array([nan, nan, nan])

np.savetxt('filedir','data')將二維數(shù)組保存到txt文件中

In [94]: np.loadtxt('nppp.txt',delimiter=',').shape Out[94]: (3, 7)In [95]: np.savetxt('ssss.txt',np.loadtxt('nppp.txt',delimiter=','))zelin@2018:~$ cat ssss.txt 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 2.000000000000000000e+00 2.000000000000000000e+00 2.000000000000000000e+00 2.000000000000000000e+00 2.000000000000000000e+00 2.000000000000000000e+00 2.000000000000000000e+00 3.000000000000000000e+00 3.000000000000000000e+00 3.000000000000000000e+00 3.000000000000000000e+00 3.000000000000000000e+00 3.000000000000000000e+00 3.000000000000000000e+00

線性代數(shù)

np.dot(x,y)和x.dot(y)得到的結(jié)果一樣

如矩陣乘法、矩陣分解、行列式以及其他方陣數(shù)學(xué),numpt提供了一個用于矩陣乘法的dot函數(shù)(既是一個數(shù)組方法也是numpy命名空間中的一個函數(shù))

In [96]: x=np.array([[1,2,3],[4,5,6]])In [97]: y=np.array([[7,8],[9,11],[12,13]])In [98]: np.dot(x,y) Out[98]: array([[ 61, 69],[145, 165]])In [99]: x.dot(y) Out[99]: array([[ 61, 69],[145, 165]])

一個二維數(shù)組跟一個大小合適的一維數(shù)組的矩陣點(diǎn)積運(yùn)算之后將會得到一個一維數(shù)組:

In [100]: x=np.array([[1,2,3],[4,5,6]])In [101]: y=np.array([1,2,3])In [102]: x.dot(y) Out[102]: array([14, 32])

numpy.linalg

linalg中由一組標(biāo)準(zhǔn)矩陣分解運(yùn)算以及諸如求逆和行列式之類的東西

In [126]: x=np.random.randn(5,5)In [127]: mat=x.T.dot(x)In [128]: inv(mat)#計算乘法的逆 Out[128]: array([[ 383.46895288, 440.98999139, 149.94498526, -163.43061669,-297.78805292],[ 440.98999139, 507.78623867, 172.63437908, -188.1462194 ,-343.09305341],[ 149.94498526, 172.63437908, 59.30910465, -64.09383187,-116.02238766],[-163.43061669, -188.1462194 , -64.09383187, 69.91440892,126.83237131],[-297.78805292, -343.09305341, -116.02238766, 126.83237131,233.04712006]])In [129]: mat.dot(inv(mat))#計算矩陣的qr分解 Out[129]: array([[ 1.00000000e+00, 5.68434189e-14, -1.27897692e-13,2.84217094e-14, 0.00000000e+00],[ 0.00000000e+00, 1.00000000e+00, 5.68434189e-14,-1.13686838e-13, 0.00000000e+00],[ 1.13686838e-13, -1.13686838e-13, 1.00000000e+00,5.68434189e-14, 0.00000000e+00],[-3.41060513e-13, -2.27373675e-13, 0.00000000e+00,1.00000000e+00, 2.27373675e-13],[-2.27373675e-13, -1.13686838e-13, -5.68434189e-14,1.13686838e-13, 1.00000000e+00]])In [130]: q,r=qr(mat)In [131]: q Out[131]: array([[-0.63453898, -0.47094923, 0.18141456, 0.19269952, -0.55274112],[ 0.7372586 , -0.20651792, 0.0060628 , 0.09058399, -0.63683428],[-0.14374066, 0.32326252, -0.7934532 , 0.44597525, -0.21535567],[ 0.05296628, -0.70849705, -0.56096271, -0.35372934, 0.23542068],[ 0.1741931 , -0.35929159, 0.15101276, 0.79413038, 0.43257184]])In [132]: r Out[132]: array([[-3.51536372e+00, 8.37098488e+00, -3.43363927e+00,4.29370726e+00, 3.78639110e+00],[ 0.00000000e+00, -5.77553574e+00, 2.53098177e+00,-7.12560115e+00, -3.36626363e+00],[ 0.00000000e+00, 0.00000000e+00, -2.65421554e+00,-3.56576864e+00, 6.19863832e-01],[ 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,-8.85238991e-01, 4.85185531e-01],[ 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,0.00000000e+00, 1.85615613e-03]])

常用的numpy.linalg函數(shù)

diag以一維數(shù)組的形式返回方針的對角線元素,或?qū)⒁痪S數(shù)組轉(zhuǎn)換為方陣
dot矩陣乘法
trace計算對角線元素的和
det計算矩陣行列式
eig計算方陣的本征值和本征向量
inv計算方陣的逆
pinv計算矩陣的Moor-Penrose偽逆
qr計算QR分解
svd計算奇異值分解
solve解線性方程組Ax=b,其中A為一個方陣
lstsq計算
??
??
??
??
??
??
??

隨機(jī)數(shù)生成

numpy.random模塊對python內(nèi)置的random進(jìn)行了補(bǔ)充,增加了一些用于高效生成多種嗯概率分布的樣本值的函數(shù),例如,用normal來得到一個標(biāo)準(zhǔn)正太分布的4*4樣本數(shù)組

In [133]: samples=np.random.normal((4,4))#與關(guān)鍵字參數(shù)不同In [134]: samples Out[134]: array([3.57761124, 2.31337006])In [135]: samples=np.random.normal(size=(4,4))In [136]: samples Out[136]: array([[ 0.78330662, -0.56505952, -0.97143979, -0.33209158],[-0.34771653, -0.30901418, -0.53225815, -0.08778485],[-1.0037474 , 0.87408366, -0.98363945, 0.5701133 ],[-1.42551243, 0.12037672, -0.49017895, 0.65434629]])

python內(nèi)置的random模塊只能一次生成一個樣本值,如果需要產(chǎn)生大量樣本值,numpy.random快了不只一個數(shù)量級

部分numpy.random函數(shù)

seed確定隨機(jī)數(shù)生成器的種子
permutation返回一個序列的隨即排列或返回一個隨即排列的范圍
shuffle對一個序列就地隨即排列
rand產(chǎn)生均勻分布的樣本值
randint從給定的上下限范圍內(nèi)隨即選區(qū)整數(shù)
randn產(chǎn)生正態(tài)分布(平均值為0,標(biāo)準(zhǔn)差為1)的樣本值
binomial產(chǎn)生二項分布的樣本值
normal產(chǎn)生正太(高斯)分布的樣本值
beta產(chǎn)生beta分布的樣本值
chisquare產(chǎn)生卡方分布的樣本值
gamma產(chǎn)生gamma分布的樣本值
uniform產(chǎn)生在[1,0)中均勻分布的樣本值
??

隨機(jī)漫步

In [136]: import random In [137]: position=0In [138]: walk=[position]In [139]: steps=1000 #純python方法 In [178]: for i in range(steps):...: step=1 if random.randint(0,2) else -1...: position+=step...: walk.append(position) #numpy方法 In [180]: nsteps=1000In [181]: draws=np.random.randint(0,2,size=nsteps)In [182]: steps=np.where(draws,1,-1)In [183]: walk=np.cumsum(steps)In [184]: walk

一次模擬多個隨即漫步

只要給numpy.random的函數(shù)傳入一個二元元組就可以產(chǎn)生一個二維數(shù)組,然后我們就可以一次性計算5000個隨即漫步過程(一行一個)的累計和了

In [185]: nsteps=5000In [186]: draws=np.random.randint(0,2,(10,500))#10行500列In [187]: walk=np.where(draws,1,-1)In [188]: np.cumsum(walk) Out[188]: array([ 1, 0, 1, ..., -60, -59, -60]) In [190]: walks.max() Out[190]: 33In [191]: walks.min() Out[191]: -75

?

數(shù)組重塑

reshape

In [15]: arr Out[15]: array([0, 1, 2, 3, 4, 5, 6, 7])In [16]: arr.reshape((4,2)) Out[16]: array([[0, 1],[2, 3],[4, 5],[6, 7]]) #多維數(shù)組也可以重塑 In [17]: arr.reshape((4,2)).reshape(2,4) Out[17]: array([[0, 1, 2, 3],[4, 5, 6, 7]]) #作為參數(shù)的形狀的其中一維可以是-1,表示該維度的大小由數(shù)據(jù)本身推斷而來 In [21]: arr.reshape((5,-1)) Out[21]: array([[ 0, 1, 2],[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11],[12, 13, 14]])In [22]: arr.reshape((3,-1)) Out[22]: array([[ 0, 1, 2, 3, 4],[ 5, 6, 7, 8, 9],[10, 11, 12, 13, 14]])#由于數(shù)組的形狀(shape)也是一個元組,因此它可以被傳入reshape: In [33]: arr1=np.ones((3,4))In [34]: arr2=np.ones((12))In [35]: arr1 Out[35]: array([[1., 1., 1., 1.],[1., 1., 1., 1.],[1., 1., 1., 1.]])In [36]: arr2 Out[36]: array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])In [37]: s=arr1.shapeIn [38]: arr2.reshape(s) Out[38]: array([[1., 1., 1., 1.],[1., 1., 1., 1.],[1., 1., 1., 1.]])

扁平化或散開

與reshape將一維數(shù)組轉(zhuǎn)換為多維數(shù)組的運(yùn)算過程相反的運(yùn)算通常稱為扁平化或散開

ravel()和flatten()

功能類似,但ravel不會產(chǎn)生源數(shù)據(jù)的副本,flatten方法返回的是源數(shù)據(jù)的副本

In [39]: arr=np.arange(15).reshape((3,5))In [40]: arr Out[40]: array([[ 0, 1, 2, 3, 4],[ 5, 6, 7, 8, 9],[10, 11, 12, 13, 14]])In [41]: arr.ravel() Out[41]: array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])In [42]: arr Out[42]: array([[ 0, 1, 2, 3, 4],[ 5, 6, 7, 8, 9],[10, 11, 12, 13, 14]])In [43]: arr.flatten() Out[43]: array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])In [44]: arr Out[44]: array([[ 0, 1, 2, 3, 4],[ 5, 6, 7, 8, 9],[10, 11, 12, 13, 14]])

C和Fortran順序

默認(rèn)情況下,Numpy數(shù)組是按行優(yōu)先順序創(chuàng)建的,在空間方面,這意味著,對于一個二維數(shù)組,每行中的數(shù)據(jù)項是被存放在相鄰內(nèi)存位置上的,另一種順序是列優(yōu)先順序,它意味著美列中的數(shù)據(jù)項是被存放在相鄰位置上的。

行優(yōu)先稱為C順序,列優(yōu)先稱為Fortran順序,像reshape,reval這樣的函數(shù),都可以接受一個表示數(shù)組數(shù)據(jù)存放順序的order參數(shù),一般可以是‘C’或‘F’,得到不同的數(shù)組

二維數(shù)組重塑過程,C和Fortran順序的關(guān)鍵區(qū)別就是維度的行進(jìn)順序

C順序:先經(jīng)過更高的維度,如軸1會優(yōu)先于軸0被處理

Forttran順序:后經(jīng)過更高的維度,如軸0會優(yōu)先于軸1被處理

In [46]: arr Out[46]: array([[ 0, 1, 2, 3],[ 4, 5, 6, 7],[ 8, 9, 10, 11]])In [47]: arr.ravel()#默認(rèn)行優(yōu)先 Out[47]: array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])In [48]: arr.ravel(order='C')#顯式行優(yōu)先 Out[48]: array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])In [49]: arr.ravel(order='F')#列優(yōu)先 Out[49]: array([ 0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11])

數(shù)組的合并與拆分

concatenate()

可以按指定軸將一個由數(shù)組組成的序列(如列表,元組等)連接到一起

In [51]: arr=np.array([[1,2,3],[4,5,6]])In [52]: arr1=np.array([[7,8,9],[10,11,12]])In [53]: np.concatenate([arr,arr1],axis=0) Out[53]: array([[ 1, 2, 3],[ 4, 5, 6],[ 7, 8, 9],[10, 11, 12]])In [54]: np.concatenate([arr,arr1],axis=1) Out[54]: array([[ 1, 2, 3, 7, 8, 9],[ 4, 5, 6, 10, 11, 12]])

vstack()和hstack()

對與常見的連接操作,也可以使用Numpy提供的vstack和hstack函數(shù)

In [56]: np.vstack((arr,arr1))#axis=0 Out[56]: array([[ 1, 2, 3],[ 4, 5, 6],[ 7, 8, 9],[10, 11, 12]])In [57]: np.hstack((arr,arr1))#axis=1 Out[57]: array([[ 1, 2, 3, 7, 8, 9],[ 4, 5, 6, 10, 11, 12]])

split()

split用于將一個數(shù)組沿指定軸拆分為多個數(shù)組

In [61]: arr=np.random.randn(5,2)In [62]: arr Out[62]: array([[-0.82230236, 0.62723821],[ 2.18883671, -0.27052682],[-0.45726504, -1.66183692],[-0.42266318, 0.84994138],[-0.30175674, 1.25396072]])In [63]: first,second,third=np.split(arr,[1,3])In [64]: first Out[64]: array([[-0.82230236, 0.62723821]])#半開放區(qū)間,邊界軸在下一個數(shù)組分區(qū)In [65]: second Out[65]: array([[ 2.18883671, -0.27052682],[-0.45726504, -1.66183692]])In [66]: third Out[66]: array([[-0.42266318, 0.84994138],[-0.30175674, 1.25396072]])

堆疊輔助類:r_和c_

使數(shù)組的堆疊操作更為簡潔

In [77]: arr=np.arange(6)In [78]: arr1=arr.reshape((3,2))In [79]: arr2=np.random.randn(3,2)In [80]: np.r_[arr1,arr2]#增加行 Out[80]: array([[ 0. , 1. ],[ 2. , 3. ],[ 4. , 5. ],[ 0.19138704, -1.34381651],[-2.13175216, -1.28283516],[-1.79236481, 0.11647346]])In [81]: np.c_[np.r_[arr1,arr2],arr]#增加列 Out[81]: array([[ 0. , 1. , 0. ],[ 2. , 3. , 1. ],[ 4. , 5. , 2. ],[ 0.19138704, -1.34381651, 3. ],[-2.13175216, -1.28283516, 4. ],[-1.79236481, 0.11647346, 5. ]])In [82]: np.c_[1:6,-10:-5]#生成數(shù)組 Out[82]: array([[ 1, -10],[ 2, -9],[ 3, -8],[ 4, -7],[ 5, -6]])

元素的重復(fù)操作:tile和repeat

對數(shù)組進(jìn)行重復(fù)以產(chǎn)生更大數(shù)組的工具主要是repeat和tile這兩個函數(shù),repeat會將數(shù)組中的各個元素重復(fù)一定次數(shù),從而產(chǎn)生一個更大的數(shù)組

In [84]: arr=np.array([1,2,3])In [85]: arr.repeat(3) Out[85]: array([1, 1, 1, 2, 2, 2, 3, 3, 3]) #默認(rèn)情況下,如果傳入的是一個整數(shù),則各元素都會重復(fù)整數(shù)次,如果傳入一組整數(shù)(元組形式),則各元素就可以重復(fù)不同的次數(shù) In [88]: arr.repeat((3,2,3))#元組長度需要與數(shù)組列數(shù)相同 Out[88]: array([1, 1, 1, 2, 2, 3, 3, 3]) #多維數(shù)組可以沿指定軸重復(fù) In [92]: arr=np.random.randn(4,5)In [93]: arr.repeat((1,2,3,4),axis=0)#按行重復(fù) Out[93]: array([[ 0.1374145 , -0.17461463, -0.3860606 , 0.37310723, -0.33203066],[-0.94992704, -0.21039861, -0.46802276, 2.23576964, -0.01360194],[-0.94992704, -0.21039861, -0.46802276, 2.23576964, -0.01360194],[-1.10704975, 2.15029587, 1.06162111, -0.76405616, -0.01180898],[-1.10704975, 2.15029587, 1.06162111, -0.76405616, -0.01180898],[-1.10704975, 2.15029587, 1.06162111, -0.76405616, -0.01180898],[ 1.39670354, 0.45674728, 1.4260907 , 2.22409618, 0.61247909],[ 1.39670354, 0.45674728, 1.4260907 , 2.22409618, 0.61247909],[ 1.39670354, 0.45674728, 1.4260907 , 2.22409618, 0.61247909],[ 1.39670354, 0.45674728, 1.4260907 , 2.22409618, 0.61247909]])In [95]: arr.repeat((1,2,3,4,5),axis=1)#按列重復(fù),即重復(fù)元素 Out[95]: array([[ 0.1374145 , -0.17461463, -0.17461463, -0.3860606 , -0.3860606 ,-0.3860606 , 0.37310723, 0.37310723, 0.37310723, 0.37310723,-0.33203066, -0.33203066, -0.33203066, -0.33203066, -0.33203066],[-0.94992704, -0.21039861, -0.21039861, -0.46802276, -0.46802276,-0.46802276, 2.23576964, 2.23576964, 2.23576964, 2.23576964,-0.01360194, -0.01360194, -0.01360194, -0.01360194, -0.01360194],[-1.10704975, 2.15029587, 2.15029587, 1.06162111, 1.06162111,1.06162111, -0.76405616, -0.76405616, -0.76405616, -0.76405616,-0.01180898, -0.01180898, -0.01180898, -0.01180898, -0.01180898],[ 1.39670354, 0.45674728, 0.45674728, 1.4260907 , 1.4260907 ,1.4260907 , 2.22409618, 2.22409618, 2.22409618, 2.22409618,0.61247909, 0.61247909, 0.61247909, 0.61247909, 0.61247909]])

tile是沿指定軸向堆疊數(shù)組的副本,可以將其想象成'鋪瓷磚',

第二參數(shù)表示瓷磚的數(shù)量,對于標(biāo)量,瓷磚是水平鋪設(shè)的,而不是垂直鋪設(shè),可以傳入一個表示鋪設(shè)布局的元組

In [96]: arr=np.random.randn(2,2)In [98]: np.tile(arr,2)#堆疊數(shù)組的副本,默認(rèn)堆疊元素 Out[98]: array([[ 0.42442511, 0.61368951, 0.42442511, 0.61368951],[ 0.25196689, -0.54785916, 0.25196689, -0.54785916]])In [99]: np.tile(arr,(2,1))#堆疊行 Out[99]: array([[ 0.42442511, 0.61368951],[ 0.25196689, -0.54785916],[ 0.42442511, 0.61368951],[ 0.25196689, -0.54785916]])In [100]: np.tile(arr,(2,3))#堆疊行2,堆疊列(元素)3 Out[100]: array([[ 0.42442511, 0.61368951, 0.42442511, 0.61368951, 0.42442511,0.61368951],[ 0.25196689, -0.54785916, 0.25196689, -0.54785916, 0.25196689,-0.54785916],[ 0.42442511, 0.61368951, 0.42442511, 0.61368951, 0.42442511,0.61368951],[ 0.25196689, -0.54785916, 0.25196689, -0.54785916, 0.25196689,-0.54785916]])

花式索引的等價函數(shù):take和put

獲取和設(shè)置數(shù)組子集的一個辦法是通過整數(shù)數(shù)組使用花式索引:

In [105]: arr=np.arange(10)*100In [106]: arr[[7,2,1,3]] Out[106]: array([700, 200, 100, 300])

ndarray有兩個方法專門用于獲取和設(shè)置單個軸向上的選區(qū):

take 是花式索引的等價函數(shù),行/列上的參數(shù)為axis=0或axis=1

put 是將花式索引表達(dá)的元素進(jìn)行替換,put不支持axis參數(shù),只能在數(shù)組的扁平化版本(一維,C順序)上進(jìn)行索引

最好的選擇還是直接使用花式索引,而不是函數(shù)

In [107]: arr=np.arange(10)*100In [108]: arr.take([7,1,2,6])#花式索引的等價函數(shù) Out[108]: array([700, 100, 200, 600])In [109]: arr.put([7,1,2,6],42)#花式索引值替換In [110]: arr Out[110]: array([ 0, 42, 42, 300, 400, 500, 42, 42, 800, 900])In [111]: arr.put([7,1,2,6],[11,22,33,44,55])#傳如入一個等長列表,同步替換In [112]: arr Out[112]: array([ 0, 22, 33, 300, 400, 500, 44, 11, 800, 900])

廣播

廣播(broadcasting)指的是不同形狀的數(shù)組之間的算術(shù)運(yùn)算的執(zhí)行方式,將標(biāo)量值跟數(shù)組合并就會發(fā)生最簡單的廣播,即標(biāo)量值被廣播到了數(shù)組的所有元素上,不同形狀指的是行數(shù)不同,列數(shù)相同才能進(jìn)行廣播。(廣播的原則:如果兩個數(shù)組的后緣維度(trailing dimension ,即從末尾開始計算起的維度)的軸長度相符或其中一方的長度為1,則認(rèn)為他們是廣播兼容的,廣播會在缺失和1長度為1的維度上進(jìn)行)

距平化:即系列數(shù)值與其平均值的差

In [120]: arr=np.random.randn(4,3)In [121]: arr.mean(0) Out[121]: array([-0.07543098, 0.83298458, -0.02126994])In [122]: arr-arr.mean(0)#由于mean(0)的長度正好為3,所以可以直接相減 Out[122]: array([[-0.27645797, 1.38328286, -1.22593655],[ 1.59969598, -0.03434764, 1.62403164],[-1.03478433, 0.31967476, 0.14974559],[-0.28845368, -1.66860997, -0.54784068]]) #由于arr.mean(0)的長度為3,所以可以直接在0軸上進(jìn)行廣播,因?yàn)閙ean(0)的后緣長度為3,所以他們是兼容的,根據(jù)廣播原則,要在1軸上作減法,則較小的那個數(shù)組形狀必須是(4,1),其中行必須是4 In [133]: res=arr.mean(1).reshape((4,1))In [134]: res Out[134]: array([[ 0.19789142],[-0.19232197],[-0.64339871],[ 0.14236788]])In [135]: arr-res Out[135]: array([[-0.90398182, 0.37917518, 0.52480664],[-0.23696029, -0.24588066, 0.48284096],[ 0.01379453, -0.22597313, 0.21217861],[-0.28368762, 0.34259934, -0.05891172]])

三維數(shù)組的廣播

高緯度數(shù)組的廣播也是遵循廣播原則的。人們經(jīng)常通過算術(shù)運(yùn)算過程將較低維度的數(shù)組在0軸以外的其他軸向上廣播,根據(jù)廣播原則,較小數(shù)組的'廣播維'必須是1,所以在進(jìn)行距平化的廣播中,較小的數(shù)組形狀必須是(N,1),不能是(N,),雖然他們表達(dá)數(shù)組視圖是相同的

下圖簡單說明了能在三維數(shù)組上廣播的二維數(shù)組

np.newaxis屬性以及'全'切片

對于三維數(shù)組,在三維中的任何一維上廣播其實(shí)也是將數(shù)據(jù)重塑為兼容的形狀而已,于是就有一個非常普遍的操作,即專門為了廣播而添加一個長度為1的新軸,Numpy數(shù)組提供了一種通過索引機(jī)制插入軸的特殊語法

In [144]: arr=np.zeros((4,4))In [145]: arr_3d=arr[:,np.newaxis,:]In [146]: arr_3d.shape Out[146]: (4, 1, 4)In [147]: arr_1d=np.random.normal(size=3)In [148]: arr_1d Out[148]: array([ 0.95908759, 0.67838227, -1.21728343])In [149]: arr_1d[:,np.newaxis] Out[149]: array([[ 0.95908759],[ 0.67838227],[-1.21728343]])In [150]: arr_1d[np.newaxis,:] Out[150]: array([[ 0.95908759, 0.67838227, -1.21728343]])

假設(shè)我們有一個三維數(shù)組,需要在軸2上進(jìn)行距平化

In [153]: arr=np.random.randn(3,4,5)In [154]: arr Out[154]: array([[[ 0.28431603, 0.44861501, -0.20777097, 0.28023136,0.17530054],[ 0.55700422, -0.14012566, 0.18500479, 1.04806987,-0.9508947 ],[-0.18838964, 0.04586741, 0.84066257, -0.07401783,1.46106524],[-0.15170269, -1.36097563, 0.59832985, 0.45333389,1.66786734]],[[-1.17441825, -0.00574066, 0.26356278, 0.82866366,-0.76109032],[ 0.10570107, -1.15842887, 0.43370703, -0.56219272,1.90148085],[-1.24608118, -0.54931805, -0.91075277, 0.21715073,0.59751696],[ 0.3297414 , -1.10564384, -0.54772233, -1.59229321,0.19203631]],[[ 2.03384505, 0.17328362, 1.59381343, 1.11969745,-0.62698893],[ 1.02854294, -0.97755266, 0.0048308 , -0.70172524,-0.12799296],[-0.42962065, 0.05177602, 0.18382527, -0.6816369 ,0.75557744],[ 0.19051328, -0.82344915, 0.90430084, 1.30163513,-0.61083626]]])In [155]: depth_means=arr.mean(2)In [156]: depth_means Out[156]: array([[ 0.19613839, 0.1398117 , 0.41703755, 0.24137055],[-0.16980456, 0.14405347, -0.37829686, -0.54477633],[ 0.85873013, -0.15477942, -0.02401576, 0.19243277]])In [157]: depth_means.shape Out[157]: (3, 4)In [158]: demeaned=arr-depth_means[:,:,np.newaxis]In [159]: demeaned Out[159]: array([[[ 0.08817763, 0.25247662, -0.40390936, 0.08409296,-0.02083785],[ 0.41719252, -0.27993736, 0.04519309, 0.90825817,-1.09070641],[-0.60542719, -0.37117014, 0.42362502, -0.49105538,1.04402769],[-0.39307324, -1.60234618, 0.35695929, 0.21196334,1.42649679]],[[-1.00461369, 0.1640639 , 0.43336734, 0.99846822,-0.59128577],[-0.03835241, -1.30248234, 0.28965356, -0.7062462 ,1.75742738],[-0.86778431, -0.17102119, -0.53245591, 0.59544759,0.97581382],[ 0.87451774, -0.56086751, -0.002946 , -1.04751687,0.73681264]],[[ 1.17511493, -0.6854465 , 0.7350833 , 0.26096733,-1.48571906],[ 1.18332236, -0.82277324, 0.15961023, -0.54694581,0.02678646],[-0.40560488, 0.07579178, 0.20784104, -0.65762114,0.7795932 ],[-0.00191949, -1.01588192, 0.71186807, 1.10920236,-0.80326902]]])In [161]: d=depth_means[:,:,np.newaxis]In [162]: d.shape Out[162]: (3, 4, 1)

通過廣播設(shè)置數(shù)組的值

算術(shù)運(yùn)算所遵循的廣播原則同樣也適用于通過索引機(jī)制設(shè)置數(shù)組值的操作,假設(shè)我們用一個一維數(shù)組來設(shè)置目標(biāo)數(shù)組的各列,只要保證兼容就可以了

In [168]: col=np.array([1.12,-0.43,0.44,1.6])In [169]: arr=np.zeros((4,3))In [170]: arr[:]=col[:,np.newaxis]In [171]: arr Out[171]: array([[ 1.12, 1.12, 1.12],[-0.43, -0.43, -0.43],[ 0.44, 0.44, 0.44],[ 1.6 , 1.6 , 1.6 ]])In [172]: arr[:2]=[[222],[333]]In [173]: arr Out[173]: array([[222. , 222. , 222. ],[333. , 333. , 333. ],[ 0.44, 0.44, 0.44],[ 1.6 , 1.6 , 1.6 ]])

ufunc高級應(yīng)用

ufunc(universal function)是指能夠應(yīng)用到ndarray對象的每一個元素上,而不僅僅是ndarray對象

reduce接受一個數(shù)組參數(shù),并通過一系列的二元運(yùn)算對其值進(jìn)行聚合(可指名軸向)

In [174]: arr=np.arange(10)In [175]: np.add.reduce(arr) Out[175]: 45In [176]: arr.sum() Out[176]: 45

np.logical_and用于檢查數(shù)組各行中的值是否是有序的,

In [177]: arr=np.random.randn(5,5)In [178]: arr[::2].sort(1)#對部分行進(jìn)行排序In [179]: arr[:,:-1]<arr[:,1:] Out[179]: array([[ True, True, True, True],[False, True, True, True],[ True, True, True, True],[False, True, False, False],[ True, True, True, True]]) #np.logical_and.reduce和all方法是等價的 In [180]: np.logical_and.reduce(arr[:,:-1]<arr[:,1:],axis=1) Out[180]: array([ True, False, True, False, True])

accumulate跟reduce的關(guān)系就像cumsum和sum的關(guān)系一樣,它產(chǎn)生一個跟原數(shù)組大小相同的中間'累計'值數(shù)組

In [181]: arr=np.arange(15).reshape(3,5)In [182]: np.add.accumulate(arr,axis=1) Out[182]: array([[ 0, 1, 3, 6, 10],[ 5, 11, 18, 26, 35],[10, 21, 33, 46, 60]])

outer用于計算兩個數(shù)組的叉積,outer輸出結(jié)果的維度是兩個輸入數(shù)據(jù)的維度之和

In [183]: arr=np.arange(3).repeat([1,2,3])In [184]: arr Out[184]: array([0, 1, 1, 2, 2, 2])In [186]: np.multiply.outer(arr,np.arange(5)) Out[186]: array([[0, 0, 0, 0, 0],[0, 1, 2, 3, 4],[0, 1, 2, 3, 4],[0, 2, 4, 6, 8],[0, 2, 4, 6, 8],[0, 2, 4, 6, 8]])#維度 In [187]: res=np.subtract.outer(np.random.randn(4,5),np.random.randn(5))In [188]: res.shape Out[188]: (4, 5, 5)

reduceat用于計算'局部約簡',其實(shí)就是一個對數(shù)據(jù)各切片進(jìn)行聚合的groupby運(yùn)算,雖然其靈活性不如pandas的groupby功能,但適當(dāng)?shù)那闆r下運(yùn)算會非常快,它接受一組用于指示如何對值進(jìn)行拆分和聚合的'面元邊界'

In [189]: arr=np.arange(10)In [190]: np.add.reduceat(arr,[0,5,8]) Out[190]: array([10, 18, 17]) #其最終結(jié)果是在arr[0:5],arr[5:8]和arr[8:]上執(zhí)行約簡(本例中就是求和),和其他方法億元,也可傳入一個axis參數(shù) In [191]: arr=np.multiply.outer(np.arange(4),np.arange(5))In [192]: arr Out[192]: array([[ 0, 0, 0, 0, 0],[ 0, 1, 2, 3, 4],[ 0, 2, 4, 6, 8],[ 0, 3, 6, 9, 12]])In [193]: np.add.reduceat(arr,[0,2,4],axis=1) Out[193]: array([[ 0, 0, 0],[ 1, 5, 4],[ 2, 10, 8],[ 3, 15, 12]])

自定義ufunc

使自定義的函數(shù)能夠像ufunc一樣使用

frompyfunc和vectorize

numpy.frompyfunc接受一個python函數(shù)以及兩個分別表示輸入輸出參數(shù)數(shù)量的整數(shù),使用frompyfunc創(chuàng)建的自定義ufunc只能返回一個python對象數(shù)組,numpy.vectorize則返回一個數(shù)組對象。

雖然這兩個函數(shù)提供了一種創(chuàng)建ufunc型函數(shù)的手段,但他們非常曼,因?yàn)樗麄冊谟嬎忝總€元素的時候都要執(zhí)行一次python函數(shù)調(diào)用,比numpy基于C的ufunc慢很多

In [194]: def add_element(x,y):...: return x+y...: In [195]: add_them=np.frompyfunc(add_element,2,1)In [196]: add_them(np.arange(8),np.arange(8)) Out[196]: array([0, 2, 4, 6, 8, 10, 12, 14], dtype=object)#vectorize返回一個數(shù)組對象 In [197]: add_them2=np.vectorize(add_element,otypes=[np.float64])In [198]: add_them2(np.arange(8),np.arange(8)) Out[198]: array([ 0., 2., 4., 6., 8., 10., 12., 14.])

結(jié)構(gòu)化和記錄式數(shù)組

ndarray是一種同質(zhì)數(shù)據(jù)容器,也就是說它所表示的內(nèi)存塊中,各元素所占用的字節(jié)數(shù)相同(具體數(shù)根據(jù)dtype而定),

結(jié)構(gòu)化數(shù)組是一種特殊的ndarray,其中各個元素可以被看作C語言中的結(jié)構(gòu)體(struct,這就是‘結(jié)構(gòu)化'的由來)或SQL表中帶有多個命名字段的行

跟pandas的DataFrame相比,結(jié)構(gòu)化數(shù)組是一種相對較低級的工具,它可以將單個內(nèi)存塊解釋為代有任意復(fù)雜嵌套列的表格型結(jié)構(gòu),由于數(shù)組中的每個元素在內(nèi)存中都被表示為固定的字節(jié)數(shù),所以結(jié)構(gòu)化數(shù)組能夠提供翡翠快速高效的的磁盤數(shù)據(jù)讀寫、網(wǎng)絡(luò)傳輸?shù)裙δ?/p>

結(jié)構(gòu)化數(shù)組的另一個用法是將數(shù)據(jù)文件寫成定長記錄字節(jié)流,只要知道文件的格式(記錄的大小、元素的順序、字節(jié)數(shù)以及數(shù)據(jù)類型),就可以用np.fromfile將數(shù)據(jù)讀入內(nèi)存---了解即可

numpy.lib.recfunctions模塊可用于操作結(jié)構(gòu)化數(shù)組--了解即可

In [199]: dtype=[('x',np.float64),('y',np.int32)]In [200]: sarr=np.array([(1.5,6),(np.pi,-2)],dtype=dtype)#np.pi 圓周率In [201]: sarr Out[201]: array([(1.5 , 6), (3.14159265, -2)],dtype=[('x', '<f8'), ('y', '<i4')])#定義結(jié)構(gòu)化dtype最典型的辦法是元組列表,各元組的格式為(field_name,field_data_type),這樣,數(shù)組的元素就成了元組式的對象,該對象中各個元素可以向字典那樣進(jìn)行訪問 In [202]: sarr[0] Out[202]: (1.5, 6)In [203]: sarr[1] Out[203]: (3.14159265, -2)In [204]: sarr[2] --------------------------------------------------------------------------- IndexError Traceback (most recent call last) <ipython-input-204-d3424412ab64> in <module>() ----> 1 sarr[2]IndexError: index 2 is out of bounds for axis 0 with size 2In [205]: sarr[0]['x'] Out[205]: 1.5In [206]: sarr[0]['y'] Out[206]: 6In [207]: sarr['y'] Out[207]: array([ 6, -2], dtype=int32) #字段名保存在dtype.name屬性中,在訪問結(jié)構(gòu)化數(shù)組在的某個字段時,返回的是該數(shù)據(jù)的視圖,所以不會發(fā)生數(shù)據(jù)復(fù)制

嵌套dtype和多維字段

在定義結(jié)構(gòu)化dtype時,可以再設(shè)置一個形狀(可以是個整數(shù),也可以是一個元組)

In [208]: dtype=[('x',np.float64,3),('',np.int32)]In [209]: arr=np.zeros(4,dtype=dtype)In [210]: arr Out[210]: array([([0., 0., 0.], 0), ([0., 0., 0.], 0), ([0., 0., 0.], 0),([0., 0., 0.], 0)], dtype=[('x', '<f8', (3,)), ('f1', '<i4')]) #各個記錄的x字段所表示的是一個長度為3的數(shù)組 In [211]: arr[0] Out[211]: ([0., 0., 0.], 0)In [212]: arr[0]['x'] Out[212]: array([0., 0., 0.]) #訪問arr['x']得到一個二維數(shù)組,而不是前面的一維數(shù)組 In [213]: arr['x'] Out[213]: array([[0., 0., 0.],[0., 0., 0.],[0., 0., 0.],[0., 0., 0.]])

這使我們能夠用單個數(shù)組的內(nèi)存塊存放復(fù)雜的數(shù)據(jù)結(jié)構(gòu),既然dtype可以想怎么復(fù)雜就怎么復(fù)雜,我們可以試試嵌套dtype,與此相比,pandas的分層索引機(jī)制跟這個差不多

In [214]: dtype=[('x',[('a','f8'),('b','f4')]),('y',np.int32)]In [215]: data=np.array([((1,2),5),((3,4),6)],dtype=dtype)In [216]: data['x'] Out[216]: array([(1., 2.), (3., 4.)], dtype=[('a', '<f8'), ('b', '<f4')])In [217]: data['y'] Out[217]: array([5, 6], dtype=int32)In [218]: data['x']['a'] Out[218]: array([1., 3.])

排序

跟python內(nèi)置的列表一樣,ndarray的sort實(shí)例方法也是就地排序,即,數(shù)組內(nèi)容的重新排序是在源數(shù)組上排序的,不會產(chǎn)生新數(shù)組的,如果排序的目標(biāo)數(shù)組只是一個視圖,則源數(shù)組將會被修改

In [219]: arr=np.random.randn(6)In [220]: arr Out[220]: array([ 0.44345783, -0.67660014, 0.13668712, -0.04890943, -0.83586259,0.61457904])In [221]: arr.sort()In [222]: arr Out[222]: array([-0.83586259, -0.67660014, -0.04890943, 0.13668712, 0.44345783,0.61457904]) #切片排序也會影響源數(shù)組 In [226]: arr=np.random.randn(6)In [227]: arr Out[227]: array([ 1.3510239 , -0.42457162, 0.70866059, -0.07718412, 1.0291165 ,1.26459721])In [228]: arr[:5].sort()In [229]: arr Out[229]: array([-0.42457162, -0.07718412, 0.70866059, 1.0291165 , 1.3510239 ,1.26459721])

numpy.sort會為源數(shù)組創(chuàng)建一個已排序副本,它接收一個數(shù)組作為參數(shù)

In [230]: arr=np.random.randn(6)In [231]: arr Out[231]: array([-0.58542925, 1.35982495, -0.80136903, -0.22464326, -0.48581381,-0.98496352])In [232]: np.sort(arr) Out[232]: array([-0.98496352, -0.80136903, -0.58542925, -0.48581381, -0.22464326,1.35982495])

ndarray.sort和np.sort(ndarray)兩個排序方法都可以接受一個axis參數(shù),以便沿指定軸向?qū)Ω鲏K數(shù)據(jù)進(jìn)行單獨(dú)排序

In [233]: arr=np.random.randn(3,5)In [234]: arr Out[234]: array([[-1.01999619, 0.73470564, -0.38008688, -1.07978726, 1.5174322 ],[-0.45355041, 0.07185554, -1.97314749, 0.00603521, 0.05596924],[-1.63445938, -0.49933928, -1.11881907, 0.03452264, 0.97180303]])In [235]: arr.sort(axis=1)In [236]: arr Out[236]: array([[-1.07978726, -1.01999619, -0.38008688, 0.73470564, 1.5174322 ],[-1.97314749, -0.45355041, 0.00603521, 0.05596924, 0.07185554],[-1.63445938, -1.11881907, -0.49933928, 0.03452264, 0.97180303]])In [237]: arr.sort(axis=0)In [238]: arr Out[238]: array([[-1.97314749, -1.11881907, -0.49933928, 0.03452264, 0.07185554],[-1.63445938, -1.01999619, -0.38008688, 0.05596924, 0.97180303],[-1.07978726, -0.45355041, 0.00603521, 0.73470564, 1.5174322 ]])

ndarray.sort()和np.sort(ndarray)兩種方法都不支持降序排列,需要在排序后使用[::-1]返回一個反序的列表

In [239]: arr=np.arange(6)In [240]: arr Out[240]: array([0, 1, 2, 3, 4, 5])In [241]: arr[::-1] Out[241]: array([5, 4, 3, 2, 1, 0])

間接排序:argsort和lexsort

在數(shù)據(jù)分析工作中,常常需要根據(jù)一個或多個鍵對數(shù)據(jù)集進(jìn)行排序,例如,一個有關(guān)學(xué)生信息的數(shù)據(jù)表可能需要以姓和名進(jìn)行排序,這就是間接排序

給定一個或多個鍵,可以得到一個由整數(shù)組成的索引數(shù)組(稱之為索引器),其中索引值說明了數(shù)據(jù)在新順序下的位置

argsort和lexsort就是實(shí)現(xiàn)該功能的兩個主要方法,pandas對象Series和DateFrame的sortindex以及Series的order方法就是通過這些函數(shù)的變體實(shí)現(xiàn)的(pandas對象需要考慮缺失值)

In [242]: values=np.array([5,0,1,3,2])In [243]: indexer=values.argsort()In [244]: indexer Out[244]: array([1, 2, 4, 3, 0])In [245]: values[indexer] Out[245]: array([0, 1, 2, 3, 5]) #根據(jù)數(shù)組的第一行對其進(jìn)行排序 In [246]: arr=np.random.randn(3,5)In [247]: arr[0]=valuesIn [248]: arr Out[248]: array([[ 5. , 0. , 1. , 3. , 2. ],[-0.62471185, 0.25591603, 0.28292862, -0.02259515, -2.22019292],[-1.29263396, 0.61927654, 0.66283367, 0.17198383, 0.13491433]])In [250]: arr[:,arr[0].argsort()] Out[250]: array([[ 0. , 1. , 2. , 3. , 5. ],[ 0.25591603, 0.28292862, -2.22019292, -0.02259515, -0.62471185],[ 0.61927654, 0.66283367, 0.13491433, 0.17198383, -1.29263396]]) #lexsorth和argsort差不多,只不過它可以一次性對多個鍵數(shù)組執(zhí)行間接排序(字典序) In [251]: first_name=np.array(['Bob','Jane','Steve','Bill','Barbara']) In [253]: last_name=np.array(['Jones','Arnold','Arnold','Jones','Walters'])In [255]: sorter=np.lexsort((first_name,last_name))In [257]: zip(last_name[sorter],first_name[sorter]) Out[257]: <zip at 0x7fabd526c9c8>In [258]: result=zip(last_name[sorter],first_name[sorter])In [259]: for i in result:...: print(i)...: ('Arnold', 'Jane') ('Arnold', 'Steve') ('Jones', 'Bill') ('Jones', 'Bob') ('Walters', 'Barbara') #因?yàn)殒I的應(yīng)用化工順序是從最后一個傳入算起的,last_name是先于first_name被應(yīng)用的

在有序數(shù)組中查找元素:searchsorted方法和digitize函數(shù)

searchsorted是一個在有序數(shù)組上執(zhí)行二分查找的數(shù)組方法,只要將值插入到它返回的那個位置就能維持?jǐn)?shù)組的有序性

In [260]: arr=np.array([0,1,3,4,6,8,9])In [261]: arr.searchsorted(7) Out[261]: 5 #傳入一組值就能得到一組索引 In [262]: arr.searchsorted([0,2,3,8]) Out[262]: array([0, 2, 2, 5]) #默認(rèn)返回相等值組的左側(cè)索引,所以0返回的是0,可設(shè)置參數(shù)side='right'返回右側(cè)的索引 In [264]: arr.searchsorted([0,2,3,8],side='right') Out[264]: array([1, 2, 3, 6])

searchsorted的另一個用法

#假設(shè)我們有一個數(shù)據(jù)數(shù)組,還有一個表示'面元邊界'的數(shù)組 In [265]: data=np.floor(np.random.uniform(0,10000,size=50))In [266]: bins=np.array([0,100,1000,5000,10000])#面元邊界In [267]: data Out[267]: array([6618., 352., 9113., 548., 4637., 5329., 2652., 4140., 7872.,9155., 8363., 8999., 4795., 6819., 7908., 9426., 9311., 1404.,1714., 9879., 9805., 2066., 664., 4675., 517., 5033., 489.,7429., 8766., 3503., 8062., 8565., 8018., 1598., 949., 7391.,4964., 7647., 7935., 7558., 5278., 6102., 2964., 9117., 9239.,7934., 4382., 4984., 2188., 1298.]) #為了得到各數(shù)據(jù)點(diǎn)所屬區(qū)間的編號(其中1表示面元[0,100],以此類推) In [268]: labels=bins.searchsorted(data)In [269]: labels Out[269]: array([4, 2, 4, 2, 3, 4, 3, 3, 4, 4, 4, 4, 3, 4, 4, 4, 4, 3, 3, 4, 4, 3,2, 3, 2, 4, 2, 4, 4, 3, 4, 4, 4, 3, 2, 4, 3, 4, 4, 4, 4, 4, 3, 4,4, 4, 3, 3, 3, 3]) #通過pandas的groupby技術(shù)可以對源數(shù)據(jù)集進(jìn)行拆分 In [271]: pd.Series(data).groupby(labels) Out[271]: <pandas.core.groupby.groupby.SeriesGroupBy object at 0x7fabd516d7b8>In [272]: pd.Series(data).groupby(labels).mean() Out[272]: 2 586.500000 3 3247.750000 4 7952.535714 dtype: float64 #Numpy的digitize函數(shù)也可用于計算面元編號, In [273]: np.digitize(data,bins) Out[273]: array([4, 2, 4, 2, 3, 4, 3, 3, 4, 4, 4, 4, 3, 4, 4, 4, 4, 3, 3, 4, 4, 3,2, 3, 2, 4, 2, 4, 4, 3, 4, 4, 4, 3, 2, 4, 3, 4, 4, 4, 4, 4, 3, 4,4, 4, 3, 3, 3, 3])

numpy的matrix類

從二維數(shù)組中選區(qū)一行[1,:]或一列[;,1]將會產(chǎn)生一個一維數(shù)組,這樣不利于矩陣運(yùn)算,numpy提供了一個matrix類,其單行或列會以二維形式返回,且使用星號(*)的乘法直接就是矩陣乘法

不建議用numpy.matrix替代正規(guī)的ndarray,因?yàn)樗麄兊膽?yīng)用面較窄,對于擁有大量線性代數(shù)運(yùn)算的函數(shù),可以考慮

In [274]: arr=np.arange(12).reshape((2,6)) #返回單行或單列返回一維數(shù)組 In [275]: arr Out[275]: array([[ 0, 1, 2, 3, 4, 5],[ 6, 7, 8, 9, 10, 11]])In [276]: arr[:,1] Out[276]: array([1, 7])In [278]: arr[1,:] Out[278]: array([ 6, 7, 8, 9, 10, 11]) #matrix類返回二維數(shù)組 In [279]: arr_m=np.matrix(arr)In [280]: arr_m[:,1] Out[280]: matrix([[1],[7]])In [281]: arr_m[1,:] Out[281]: matrix([[ 6, 7, 8, 9, 10, 11]])

matrix還有一個特殊屬性I,其功能是返回矩陣的逆

In [282]: arr=np.arange(12).reshape((2,6))In [283]: arr_m=np.matrix(arr)In [284]: arr_m.I Out[284]: matrix([[-0.23015873, 0.08730159],[-0.14920635, 0.06349206],[-0.06825397, 0.03968254],[ 0.01269841, 0.01587302],[ 0.09365079, -0.00793651],[ 0.17460317, -0.03174603]])

內(nèi)存映像文件

內(nèi)存映像,功能是能夠處理在內(nèi)存中放不下的數(shù)據(jù)集

內(nèi)存映像文件是一種將磁盤上的非常大的二進(jìn)制數(shù)據(jù)文件當(dāng)作內(nèi)存中的數(shù)組進(jìn)行處理的方式,numpy實(shí)現(xiàn)了一個類似于ndarray的memmap對象,它允許將大文件分成小段進(jìn)行讀寫,而不是一次性將整個數(shù)組讀入內(nèi)存。memmap也擁有和數(shù)組一樣的方法,基本上只要是能用于ndarray的算法,也能用于memmap

使用函數(shù)np.memmap并傳入文件路徑、數(shù)據(jù)類型、形狀以及文件模式,即可創(chuàng)建一個memmap

In [285]: mmap=np.memmap('mymmap',dtype='float64',mode='w+',shape=(10000,10000))...: In [286]: mmap Out[286]: memmap([[0., 0., 0., ..., 0., 0., 0.],[0., 0., 0., ..., 0., 0., 0.],[0., 0., 0., ..., 0., 0., 0.],...,[0., 0., 0., ..., 0., 0., 0.],[0., 0., 0., ..., 0., 0., 0.],[0., 0., 0., ..., 0., 0., 0.]]) #對memmap切片會返回磁盤上的數(shù)據(jù)的視圖,如果將數(shù)據(jù)賦值給這些視圖,數(shù)據(jù)會顯緩存在內(nèi)存中(就向python的文件對象),調(diào)用flush即可將其寫入磁盤In [287]: mmap[:5] Out[287]: memmap([[0., 0., 0., ..., 0., 0., 0.],[0., 0., 0., ..., 0., 0., 0.],[0., 0., 0., ..., 0., 0., 0.],[0., 0., 0., ..., 0., 0., 0.],[0., 0., 0., ..., 0., 0., 0.]])In [288]: section=mmap[:5]In [289]: section[:]=np.random.randn(5,10000)In [290]: mmap.flush()In [291]: mmap Out[291]: memmap([[ 1.58111002, 1.90645244, -0.63471948, ..., -1.35606172,1.16922047, 0.3476418 ],[ 0.48324066, 0.63520092, -0.5317452 , ..., 0.69026956,0.35725548, -0.33512981],[ 0.43491278, -1.47961165, -0.17788593, ..., 2.36128756,0.93145793, -0.38050151],...,[ 0. , 0. , 0. , ..., 0. ,0. , 0. ],[ 0. , 0. , 0. , ..., 0. ,0. , 0. ],[ 0. , 0. , 0. , ..., 0. ,0. , 0. ]])In [292]: del mmap #刪除內(nèi)存映像#只要某個內(nèi)存映像超出了作用域,它就會被垃圾回收器回收,之前對其所作的任何修改都會被寫入磁盤,當(dāng)打開一個已經(jīng)存在的內(nèi)存映像時,仍然需要指明數(shù)據(jù)類型和形狀,因?yàn)榇疟P上的那個文件只是一塊二進(jìn)制數(shù)據(jù)而已,沒有任何元數(shù)據(jù) In [293]: mmap=np.memmap('mymmap',dtype='float64',shape=(10000,10000))In [294]: mmap Out[294]: memmap([[ 1.58111002, 1.90645244, -0.63471948, ..., -1.35606172,1.16922047, 0.3476418 ],[ 0.48324066, 0.63520092, -0.5317452 , ..., 0.69026956,0.35725548, -0.33512981],[ 0.43491278, -1.47961165, -0.17788593, ..., 2.36128756,0.93145793, -0.38050151],...,[ 0. , 0. , 0. , ..., 0. ,0. , 0. ],[ 0. , 0. , 0. , ..., 0. ,0. , 0. ],[ 0. , 0. , 0. , ..., 0. ,0. , 0. ]])

性能建議

使用numpy的數(shù)組運(yùn)算一般都比純python循環(huán)快得多,大致注意以下事項:

將python循環(huán)和條件邏輯轉(zhuǎn)換為數(shù)組運(yùn)算和布爾數(shù)組運(yùn)算

盡量使用廣播

避免復(fù)制數(shù)據(jù),盡量使用數(shù)組視圖(即切片)

利用ufunc及其各種方法

Cpython和numpy

可以將Cpython看作帶有靜態(tài)類型并能嵌入C函數(shù)的python,Cpython實(shí)現(xiàn)的代碼運(yùn)行速度很快,下面是簡單的Cpython函數(shù)用于對一個和一維數(shù)組求和

from numpy cimport ndarray,float64_t def sum_element(ndarray[float64_t] arr):cdef py_ssize_t i,n=len(arr)cdef float64_t result=0for i in range(n):result+=arr[i]return result#Cpython處理這段代碼時,先將其翻譯為C代碼,然后編譯這些C代碼并創(chuàng)建一個python擴(kuò)展,一般的工作流程是:得到能在python中運(yùn)行的算法,然后再將其翻譯為Cpython(只需添加類型定義并完成一些其他必要的工作即可--只需你妹!!)

?

?

二 pandas模塊

1.pandas的數(shù)據(jù)結(jié)構(gòu):

Series

Series 是一維標(biāo)簽數(shù)組(Data must be 1-dimension),能夠保存任何數(shù)據(jù)類型(整型,浮點(diǎn)型,字符串或其他Python對象類型)。軸標(biāo)簽被稱為索引

>>> import numpy as np >>> import pandas as pd >>> pd.Series(np.random.randn(12))#Series函數(shù)用于創(chuàng)建Series 0 0.445457 1 1.410470 2 -0.669725 3 -0.907310 4 0.081393 5 0.034115 6 1.219609 7 0.135690 8 -0.353035 9 0.640904 10 0.218566 11 0.836471 dtype: float64 >>> pd.Series(np.random.randn(12).reshape(3,4))#只能傳如一維數(shù)組,否則會報錯 Traceback (most recent call last):File "<stdin>", line 1, in <module>File "/home/zelin/.local/lib/python3.6/site-packages/pandas/core/series.py", line 275, in __init__raise_cast_failure=True)File "/home/zelin/.local/lib/python3.6/site-packages/pandas/core/series.py", line 4165, in _sanitize_arrayraise Exception('Data must be 1-dimensional') Exception: Data must be 1-dimensional

Series的字符串表現(xiàn)形式為:索引在左邊,值在右邊,如果沒有為數(shù)據(jù)指定索引,Series會自動創(chuàng)建一個0到N-1(N為數(shù)據(jù)長度)的整數(shù)型索引

values、index和name

Series的values屬性和index屬性為數(shù)組類型,Series調(diào)用values或index后返回一個帶由值或索引的數(shù)組

Series對象本身和其索引都有一個name屬性,該功能和pandas的其他關(guān)鍵功能關(guān)系非常密切(需要設(shè)置,默認(rèn)為空)

In [192]: obj=pd.Series([111,222,333,444,555])In [193]: obj Out[193]: 0 111 1 222 2 333 3 444 4 555 dtype: int64In [194]: obj.index Out[194]: RangeIndex(start=0, stop=5, step=1)In [195]: obj.values Out[195]: array([111, 222, 333, 444, 555])

創(chuàng)建Series索引

Series的索引/切片形式同python的數(shù)據(jù)類型列表字典類似,可以將Series看成是一個定長的有序字典,因?yàn)樗撬饕档綌?shù)據(jù)值的一個映射,同樣,Series也可以進(jìn)行索引賦值就地修改

In [197]: ser=pd.Series([111,222,333],index=['a','b','c'])In [198]: ser Out[198]: a 111 b 222 c 333 dtype: int64

可以傳入字典來創(chuàng)建一個Series,如果只傳字典一個參數(shù),則字典的鍵作為Series的索引,字典的值作為Series的值

如果傳入字典參數(shù)后,另外指定索引參數(shù),則索引如果與字典的鍵不匹配,則以索引產(chǎn)生一個NaN值,如果索引與字典的鍵匹配,則產(chǎn)生的值等于字典的值,即字典的鍵不產(chǎn)生作用

In [199]: pd.Series({'a':111,'b':222}) Out[199]: a 111 b 222 dtype: int64In [200]: In [200]: pd.Series({'a':111,'b':222},index=['ccc','ddd']) Out[200]: ccc NaN ddd NaN dtype: float64

Series最重要的一個功能是,它在算術(shù)運(yùn)算中會自動對其不同索引的數(shù)據(jù),即兩個Series的相同索引進(jìn)行運(yùn)算,不同索引產(chǎn)生NaN值

In [201]: ser1=pd.Series({'a':1,'b':2,'c':3})In [202]: ser2=pd.Series({'c':3,'d':4,'e':5})In [203]: ser1+ser2 Out[203]: a NaN b NaN c 6.0 d NaN e NaN dtype: float64

isnull和notnull

判斷Series數(shù)據(jù)是否為NaN值

In [212]: ser=pd.Series({'a':1,'b':2,'c':3,'d':np.nan})In [213]: pd.isnull(ser) Out[213]: a False b False c False d True dtype: boolIn [214]: pd.notnull(ser) Out[214]: a True b True c True d False dtype: bool

?

?

DataFrame

DataFrame是一個2維標(biāo)簽的數(shù)據(jù)結(jié)構(gòu),是一種表格型數(shù)據(jù)結(jié)構(gòu),它的列可以存在不同的類型,你可以把它簡單的想成Excel表格或SQL Table,或者是包含字典類型的Series。它是最常用的Pandas對象。和Series一樣,DataFrame接受許多不同的類型輸入:

??? 包含1維ndarray,列表對象,字典對象或者Series對象的字典對象
??? 2維的ndarray對象
??? 結(jié)構(gòu)化或記錄型的ndarray
??? Series對象
??? 另一個DataFrame對象

#np.random.randn(12)產(chǎn)生一個服從正態(tài)分布的12個數(shù)字的一維數(shù)組,reshape(3,4)將數(shù)組重構(gòu)為3行4列的二維數(shù)組 >>> pd.DataFrame(np.random.randn(12).reshape(3,4))#DataFrame函數(shù)用于創(chuàng)建DataFrame0 1 2 3 0 -0.862802 1.176531 -0.009699 -0.455003 1 1.051637 -0.199708 0.402293 0.014919 2 0.588871 0.059458 1.911373 2.224995

創(chuàng)建DataFrame

創(chuàng)建DataFrame的方法有很多很多,最常用的一種是直接傳入一個由長列表或數(shù)組組成的數(shù)組

data_dict={'states':['oooo','ssss','dddd'],'age':[11,12,12]} In [3]: df=pd.DataFrame(data_dict,index...: =['aaa','bbb','ccc'])In [4]: df Out[4]: states age aaa oooo 11 bbb ssss 12 ccc dddd 12 #如果制定類列的序列,則會根據(jù)序列排序 In [8]: df=pd.DataFrame(data_dict,index=['aaa','bbb','ccc'],columns=['age','stat...: es'])In [9]: df Out[9]: age states aaa 11 oooo bbb 12 ssss ccc 12 dddd#如果傳入的列序列在數(shù)據(jù)中找不到,則會產(chǎn)生NaN值 In [10]: df=pd.DataFrame(data_dict,index=['aaa','bbb','ccc'],columns=['age','sta...: tes','NAN']) In [11]: df Out[11]: age states NAN aaa 11 oooo NaN bbb 12 ssss NaN ccc 12 dddd NaN

索引切片

通過類似字典標(biāo)記的方法,可以將DataFrame的列轉(zhuǎn)化為一個Series,返回的Series擁有原DataFrame相同的索引,且其name屬性也已經(jīng)被相應(yīng)地設(shè)置好了

In [10]: df=pd.DataFrame(data_dict,index=['aaa','bbb','ccc'],columns=['age','sta...: tes','NAN'])In [11]: df Out[11]: age states NAN aaa 11 oooo NaN bbb 12 ssss NaN ccc 12 dddd NaNIn [12]: df['age'] Out[12]: aaa 11 bbb 12 ccc 12 Name: age, dtype: int64

行也可以通過位置或者名稱的方式進(jìn)行獲取,比如用索引字段ix

In [15]: df.ix['aaa'] Out[15]: age 11 states oooo NAN NaN Name: aaa, dtype: object

列可以通過賦值的方式進(jìn)行修改(整列發(fā)生改變),若賦值的列名不存在,則會新增一列

In [16]: df['age']=100In [17]: df Out[17]: age states NAN aaa 100 oooo NaN bbb 100 ssss NaN ccc 100 dddd NaNIn [18]: df['num']=200In [19]: df Out[19]: age states NAN num aaa 100 oooo NaN 200 bbb 100 ssss NaN 200 ccc 100 dddd NaN 200

通過索引方式返回的列只是源數(shù)據(jù)的視圖,而不是副本,所以對返回的列進(jìn)行修改,也會反映到源數(shù)據(jù),修改列時可能會由警告,keying忽略不計

In [19]: df Out[19]: age states NAN num aaa 100 oooo NaN 200 bbb 100 ssss NaN 200 ccc 100 dddd NaN 200In [20]: sr=df['age']In [21]: sr['aaa']=3000 /home/zelin/anaconda3/bin/ipython:1: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrameSee the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy#!/home/zelin/anaconda3/bin/pythonIn [22]: sr Out[22]: aaa 3000 bbb 100 ccc 100 Name: age, dtype: int64In [23]: df Out[23]: age states NAN num aaa 3000 oooo NaN 200 bbb 100 ssss NaN 200 ccc 100 dddd NaN 200

如果給DataFrame傳入一個嵌套字典,即字典的值也是字典,它就會被解釋成:外層字典的鍵作為列,內(nèi)層字典的鍵作為行

In [25]: df=pd.DataFrame({'ooo':{1:1,2:2,3:3},'ppp':{11:11,22:22,33:33,44:44}})In [27]: df Out[27]: ooo ppp 1 1.0 NaN 2 2.0 NaN 3 3.0 NaN 11 NaN 11.0 22 NaN 22.0 33 NaN 33.0 44 NaN 44.0

對DataFrame進(jìn)行轉(zhuǎn)置,內(nèi)層字典的鍵會被合并、排序以形成最終的索引,如果顯式指定列索引,則不會這樣

In [32]: df2=pd.DataFrame(df,index=(1,2,3,11,33))In [33]: df2 Out[33]: ooo ppp 1 1.0 NaN 2 2.0 NaN 3 3.0 NaN 11 NaN 11.0 33 NaN 33.0

可以輸入給DataFrame構(gòu)造器的數(shù)據(jù)

類型說明
二維ndarray數(shù)據(jù)矩陣,還可以傳入行標(biāo)和列標(biāo)
由數(shù)組、列表、元組組成的字典每個序列會變成DataFrame的一列,所有序列的長度必須相同
由Series組成的字典每個Series會成一列。如果沒有顯式指定索引,則各Series的索引會被合并成結(jié)果的行索引
由字典組成的字典各內(nèi)層字典會成為一列,鍵會被合并成結(jié)果的行索引,跟‘由Series組成的字典’的情況一樣
字典或Series的列表各項會成為DataFrame的一行,字典鍵或Series的索引的并集會成為DataFrame的列標(biāo)
由列表或元組組成的列表類似二維ndarray
另一個DataFrame該DataFrame的索引將會被沿用,除非顯式指定了其他索引
numpy的maskedArray類似二維ndarray的情況,只是掩碼值在結(jié)果DataFrame會變成NA缺失值
??

如果設(shè)置了index和columns的name屬性,則這些信息會被顯式出來

In [34]: df=pd.DataFrame({'ooo':{1:1,2:2,3:3},'ppp':{11:11,22:22,33:33,44:44}})In [35]: df.index.name='year'In [36]: df.columns.name='state'In [37]: df Out[37]: state ooo ppp year 1 1.0 NaN 2 2.0 NaN 3 3.0 NaN 11 NaN 11.0 22 NaN 22.0 33 NaN 33.0 44 NaN 44.0

跟Series一樣,values屬性也會以二維ndarray的形式返回DataFrame中的數(shù)據(jù)

In [38]: df.values Out[38]: array([[ 1., nan],[ 2., nan],[ 3., nan],[nan, 11.],[nan, 22.],[nan, 33.],[nan, 44.]])

如果DataFrame各列的數(shù)據(jù)類型不同,則值數(shù)組的數(shù)據(jù)類型就會選用能兼容所有列的數(shù)據(jù)類型、

In [48]: df=pd.DataFrame({'a':1,'b':'b','c':3.44},index=['a','b','c'])In [49]: df.values Out[49]: array([[1, 'b', 3.44],[1, 'b', 3.44],[1, 'b', 3.44]], dtype=object)

如果字典的鍵的值只有一個,DateFrame的行數(shù),會根據(jù)顯式指定的index的長度而變化,值重復(fù)

In [39]: df=pd.DataFrame({'a':1,'b':'b','c':3.44},index=['a'])In [40]: df Out[40]: a b c a 1 b 3.44In [41]: df=pd.DataFrame({'a':1,'b':'b','c':3.44},index=['a','b'])In [42]: df Out[42]: a b c a 1 b 3.44 b 1 b 3.44In [43]: df=pd.DataFrame({'a':1,'b':'b','c':3.44},index=['a','b','c'])In [44]: df Out[44]: a b c a 1 b 3.44 b 1 b 3.44 c 1 b 3.44

索引對象

pandas的索引對象負(fù)責(zé)管理軸標(biāo)簽和其他元數(shù)據(jù)(比如軸名稱等),構(gòu)建Series或DataFrame時,所用到的任何數(shù)組或者其他序列都會被轉(zhuǎn)化成一個index,Index對象是不可修改的(immutable),因此用戶不能對其進(jìn)行修改(--否則會報錯)

In [50]: df=pd.DataFrame({'a':1,'b':'b','c':3.44},index=['a','b','c'])In [51]: df Out[51]: a b c a 1 b 3.44 b 1 b 3.44 c 1 b 3.44In [52]: index=df.indexIn [53]: index Out[53]: Index(['a', 'b', 'c'], dtype='object')In [54]: index[1] Out[54]: 'b'In [55]: index[1]='a' --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-55-336c3a4c2807> in <module>() ----> 1 index[1]='a'~/anaconda3/lib/python3.7/site-packages/pandas/core/indexes/base.py in __setitem__(self, key, value)2063 2064 def __setitem__(self, key, value): -> 2065 raise TypeError("Index does not support mutable operations")2066 2067 def __getitem__(self, key):TypeError: Index does not support mutable operations

不可修改性非常重要,因?yàn)檫@樣才能使Index對象在多個數(shù)據(jù)結(jié)構(gòu)之間安全共享,Index可以被集成從而實(shí)現(xiàn)特別的軸索引功能

In [57]: index=pd.Index(np.arange(3))In [58]: obj2=pd.Series([111,222,333],index=index)In [59]: obj2.index is index Out[59]: True

Index長的像數(shù)組,功能也類似一個固定大小的集合

In [58]: obj2=pd.Series([111,222,333],index=index)In [59]: obj2.index is index Out[59]: TrueIn [60]: 1 in obj2.index Out[60]: TrueIn [61]: 222 in obj2.index Out[61]: False

每個索引都有一些方法和屬性,他們可用于設(shè)置邏輯并回答有關(guān)該索引所包含的數(shù)據(jù)的常見問題

方法說明
append

鏈接另一個Index對象,產(chǎn)生一個新的Index對象

diff計算差集,并得到一個Index
intersection計算交集
union計算并集
isin計算一個指示各值是否都包含在參數(shù)集合種的布爾型數(shù)組
delete刪除索引i處的元素,并得到一個新的Index
drop刪除傳入的值,并得到新的Index
insert將元素插入索引i處,并得到一個新的Index
is_monotonic當(dāng)各元素均大于等于前一個值時,返回True
is_unique當(dāng)Index沒有重復(fù)值時,返回True
unique計算Index中唯一值的數(shù)組

Series和DataFrame的基本功能

重新索引reindex,其作用是創(chuàng)建一個適應(yīng)新索引的新對象,調(diào)用Series的reindex將會根據(jù)新索引重排,如果某個索引值當(dāng)前不存在,就引入缺失值,reindex的參數(shù)fill_value用以替換數(shù)據(jù)內(nèi)的缺失值

In [62]: obj=pd.Series([1,2,3,4],index=['d','b','a','c'])In [64]: obj Out[64]: d 1 b 2 a 3 c 4 dtype: int64In [65]: obj.reindex(['a','b','c','d','e'])#重新排序,及某個索引值當(dāng)前不存在,則引入缺失值 Out[65]: a 3.0 b 2.0 c 4.0 d 1.0 e NaN dtype: float64In [66]: obj.reindex(['a','b','c','d','e','f'],fill_value=1.1)#fill_value替換缺失值 Out[66]: a 3.0 b 2.0 c 4.0 d 1.0 e 1.1 f 1.1 dtype: float64

如果像時間序列這樣的有序數(shù)據(jù),重新索引時可能需要做一些插值處理,method選項即可達(dá)到此目的,例如使用method=ffill可以實(shí)現(xiàn)向前填充(即復(fù)制排序前位的值),以及method=bfill向后填充(復(fù)制排序后位的值)

In [67]: obj=pd.Series(['blue','yellow','orange'],index=[0,2,4])In [68]: obj.reindex(np.arange(6)) Out[68]: 0 blue 1 NaN 2 yellow 3 NaN 4 orange 5 NaN dtype: objectIn [69]: obj.reindex(np.arange(6),method='ffill') Out[69]: 0 blue 1 blue 2 yellow 3 yellow 4 orange 5 orange dtype: objectIn [70]: obj=pd.Series(['blue','yellow','orange'],index=[0,2,4])In [71]: obj.reindex(np.arange(6),method='bfill')#后面沒有數(shù)據(jù),則仍然為NaN值 Out[71]: 0 blue 1 yellow 2 yellow 3 orange 4 orange 5 NaN dtype: object

重新索引行和列或者都修改,傳入單個序列默認(rèn)修改行索引,修改列標(biāo)需要傳參給columns參數(shù),但插值只能按行應(yīng)用

In [73]: df=pd.DataFrame(np.arange(9).reshape(3,3),index=['a','b','c'],columns=[...: 'va','vb','vc'])In [74]: df Out[74]: va vb vc a 0 1 2 b 3 4 5 c 6 7 8In [75]: df.reindex(['a','b','c','d']) Out[75]: va vb vc a 0.0 1.0 2.0 b 3.0 4.0 5.0 c 6.0 7.0 8.0 d NaN NaN NaNIn [76]: df.reindex(columns=['vvva','vvvb','vvvc']) Out[76]: vvva vvvb vvvc a NaN NaN NaN b NaN NaN NaN c NaN NaN NaN

利用ix的標(biāo)簽索引功能,重新索引更簡潔

In [77]: df=pd.DataFrame(np.arange(9).reshape(3,3),index=['a','b','c'],columns=[...: 'va','vb','vc'])In [78]: df Out[78]: va vb vc a 0 1 2 b 3 4 5 c 6 7 8In [79]: df.ix[['a','b','c','d'],['vva','vvb','vc']]Out[79]: vva vvb vc a NaN NaN 2.0 b NaN NaN 5.0 c NaN NaN 8.0 d NaN NaN NaN

reindex函數(shù)的參數(shù)

參數(shù)說明
index用作索引的新序列,既可以是Index實(shí)例,也可以是其他序列型的python數(shù)據(jù)結(jié)構(gòu),Index會被完全使用,就像沒有任何復(fù)制一樣
method插值(填充)方式
fill_value在重新索引過程種,需要引入缺失值使用的替代值
limit前向或后向填充時的最大填充量
level在Multilndex在指定級別上匹配簡單索引,否則選取其子集
copy默認(rèn)為True,無論如何都復(fù)制,如果為False,則新舊相等就不復(fù)制

?

刪除指定軸上的項

drop方法

丟棄某條軸上的一個或多個項,只要有一個索引數(shù)組 或者列表即可,由于需要執(zhí)行一些數(shù)據(jù)整理和集合邏輯,所以drop方法返回的是一個在指定軸上刪除了指定值的新對象

In [3]: ser=pd.Series(np.arange(5.),index=['a','b','c','d','e'])In [4]: ser Out[4]: a 0.0 b 1.0 c 2.0 d 3.0 e 4.0 dtype: float64In [5]: ser.drop('c')#獲取到的是新對象,而不是刪除源數(shù)據(jù) Out[5]: a 0.0 b 1.0 d 3.0 e 4.0 dtype: float64In [6]: ser Out[6]: a 0.0 b 1.0 c 2.0 d 3.0 e 4.0 dtype: float64

索引、選取和過濾

Series的索引的工作方式類似numpy數(shù)組的索引,只不過Series的索引不只是整數(shù),而且與普通python的切片不同,其末端是包含的(即封閉區(qū)間),索引就是一個數(shù)據(jù),切片就是切一片數(shù)據(jù)

In [12]: obj=pd.Series(np.arange(4.),index=('a','b','c','d'))In [13]: obj Out[13]: a 0.0 b 1.0 c 2.0 d 3.0 dtype: float64In [14]: obj['a':'c'] Out[14]: a 0.0 b 1.0 c 2.0 dtype: float64

索引方式幾種特殊的情況,通過切片或布爾型數(shù)組選取行

In [15]: obj=pd.Series(np.arange(4.),index=('a','b','c','d'))In [16]: obj>2 Out[16]: a False b False c False d True dtype: boolIn [18]: obj[obj>2] Out[18]: d 3.0 dtype: float64

索引字段ix

可以通過Numpy式的標(biāo)記法以及軸標(biāo)簽從DataFrame中選取行和列的子集

In [31]: df=pd.DataFrame(np.arange(16).reshape(4,4),index=['o','p','q','r'],colu...: mns=['one','two','three','four'])In [37]: df Out[37]: one two three four o 0 1 2 3 p 4 5 6 7 q 8 9 10 11 r 12 13 14 15In [32]: df.ix['o',['one','two']]#[行索引,列標(biāo)] Out[32]: one 0 two 1 Name: o, dtype: int64In [34]: df.ix[['o','p'],['one','two']]#位置參數(shù),無需指定Out[34]: one two o 0 1 p 4 5In [36]: df.ix[df.one>3,:3]#one列大于3的所有數(shù)據(jù)Out[36]: one two three p 4 5 6 q 8 9 10 r 12 13 14

DataFrame的索引選項

obj[val]選取DataFrame的單個列或一組列,在一些特殊情況下會比較便利::布爾型數(shù)組(過濾行),切片(行切片),布爾型DataFrame(根據(jù)條件設(shè)置值)
obj.ix[val]選取DataFrame的單個行或一組行
obj.ix[:,val]選取單個列或列子集
obj.ix[[vla1,val2]]同時選取行和列(參數(shù)1為行,參數(shù)2為列)
reindex方法將一個或多個軸匹配到新索引
xs方法根據(jù)標(biāo)簽選取單行或單列,并返回一個Series

icol、irow方法

根據(jù)整數(shù)位置選取單列或單行

get_value、set_value

根據(jù)行標(biāo)簽和列標(biāo)簽選取單個值

算術(shù)運(yùn)算和數(shù)據(jù)對齊

pandas最重要的一個功能,它可以對不同索引的對象進(jìn)行算術(shù)運(yùn)算,在將對象相加時,如果存在不同的索引對,則該結(jié)果的索引對的并集(相同索引相加,不同索引并集,取空值NaN),自動的數(shù)據(jù)對齊操作在不重疊的索引處引入列NA值,缺失值會在算術(shù)運(yùn)算種傳播

In [39]: s1=pd.Series([1,2,3,4],index=['a','c','d','e'])In [42]: s2=pd.Series([3,3,3,3,3],index=['a','c','e','f','g'])In [43]: s1+s2 Out[43]: a 4.0 c 5.0 d NaN e 7.0 f NaN g NaN dtype: float64

DataFrame的對齊操作

對于DataFrame,對齊操作會同時發(fā)生在行和列上,把他們相加后會返回一個新的DataFrame,其索引和列標(biāo)為原來兩個DataFrame的并集(索引和列標(biāo)不全相同,則為NaN,全相等則相加)

In [45]: df1=pd.DataFrame(np.arange(9).reshape(3,3),columns=list('bcd'),index=li...: st('xyz'))In [48]: df2=pd.DataFrame(np.arange(12.).reshape(4,3),columns=list('dbe'),index=...: list('xymn'))In [49]: df1+df2 Out[49]: b c d e m NaN NaN NaN NaN n NaN NaN NaN NaN x 1.0 NaN 2.0 NaN y 7.0 NaN 8.0 NaN z NaN NaN NaN NaN

在算術(shù)方法中的填充值

兩個DataFrame相加,不重疊部分會產(chǎn)生空值NaN,使用add方法將兩個DataFrame相加可以,以及一個fill_value參數(shù),可以實(shí)現(xiàn)將不重疊部分填充值,然后再相加

In [11]: import numpy as npIn [12]: import pandas as pdIn [13]: df1=pd.DataFrame(np.arange(12).reshape((3,4)),columns=list('abcd'))In [14]: df2=pd.DataFrame(np.arange(20).reshape((4,5)),columns=list('abcde'))In [15]: df1+df2 Out[15]: a b c d e 0 0.0 2.0 4.0 6.0 NaN 1 9.0 11.0 13.0 15.0 NaN 2 18.0 20.0 22.0 24.0 NaN 3 NaN NaN NaN NaN NaNIn [16]: df1.add(df2) Out[16]: a b c d e 0 0.0 2.0 4.0 6.0 NaN 1 9.0 11.0 13.0 15.0 NaN 2 18.0 20.0 22.0 24.0 NaN 3 NaN NaN NaN NaN NaNIn [17]: df1.add(df2,fill_value=0)#并非在結(jié)果中填充,而是將不重疊部分填充為0值 Out[17]: a b c d e 0 0.0 2.0 4.0 6.0 4.0 1 9.0 11.0 13.0 15.0 9.0 2 18.0 20.0 22.0 24.0 14.0 3 15.0 16.0 17.0 18.0 19.0

與此類似,在對Series和DataFrame重新索引時,也可以指定一個填充值(reindex重新索引產(chǎn)生的是新數(shù)據(jù),不會影響源數(shù)據(jù),所以df1可以用兩次)

In [20]: df1.reindex(list('abcde'),fill_value=0) Out[20]: a b c d a 0 0 0 0 b 0 0 0 0 c 0 0 0 0 d 0 0 0 0 e 0 0 0 0In [21]: df1.reindex(columns=list('abcde'),fill_value=0)#重新索引產(chǎn)生的是新數(shù)據(jù),不會影響源數(shù)據(jù) Out[21]: a b c d e 0 0 1 2 3 0 1 4 5 6 7 0 2 8 9 10 11 0

算術(shù)方法:加減乘除

df1.add(df2)
df1.sub(df2)
df1.mul(df2)
df1.div(df2)


?

?

?

?

DataFrame和Series之間的運(yùn)算

跟numpy一樣,DataFrame和Series之間的算術(shù)運(yùn)算也是有明確規(guī)定的

廣播:即DataFrame和Series算術(shù)運(yùn)算,會沒廣播到全DataFrame都和Series都進(jìn)行運(yùn)算,而不僅僅是單列/行

DataFrame和Series之間的算術(shù)運(yùn)算會將Series的索引匹配到DataFrame的列,然后沿著行一直向下廣播,如果某個索引值在DataFrame的列或Series的索引種找不到,則參與運(yùn)算的兩個對象就會被重新索引引以形成并集

默認(rèn)匹配列,沿著行傳波

In [25]: df=pd.DataFrame(np.arange(12).reshape((4,3)),index=list('abcd'),columns...: =list('opq'))In [26]: df Out[26]: o p q a 0 1 2 b 3 4 5 c 6 7 8 d 9 10 11In [27]: ser=df.ix['a']#只能以行索引為參數(shù),不然會報錯In [28]: ser Out[28]: o 0 p 1 q 2 Name: a, dtype: int64In [30]: df.add(ser) Out[30]: o p q a 0 2 4 b 3 5 7 c 6 8 10 d 9 11 13In [31]: df+ser Out[31]: o p q a 0 2 4 b 3 5 7 c 6 8 10 d 9 11 13

如果你希望匹配到行且在列上廣播,則必須使用算術(shù)運(yùn)算方法

In [33]: df.add(ser,axis=0)#匹配行,即將Series的列標(biāo)成為索引與DataFrame 并集 Out[33]: o p q a NaN NaN NaN b NaN NaN NaN c NaN NaN NaN d NaN NaN NaN o NaN NaN NaN p NaN NaN NaN q NaN NaN NaN

函數(shù)的應(yīng)用和映射

Numpy的ufuncs(元素級數(shù)組方法)也可以用于操作pandas對象

另一個常見的操作是,將函數(shù)應(yīng)用到由各列或行所形成的一維數(shù)組上,DataFrame的apply方法可實(shí)現(xiàn)此功能

apply,應(yīng)用作為參數(shù)傳入的函數(shù)/方法功能

In [10]: df=pd.DataFrame(np.arange(12).reshape((4,3)),columns=list('xyz'),index=...: list('adcd'))In [11]: f=lambda x: x.max()-x.min()In [12]: df.apply(f)#使用作為參數(shù)傳入的函數(shù)功能 Out[12]: x 9 y 9 z 9 dtype: int64In [13]: df.apply(f,axis=1) Out[13]: a 2 d 2 c 2 d 2 dtype: int64

applymap 函數(shù)應(yīng)用

元素級的python函數(shù)也是可以用的,使用applymap即可

In [15]: df=pd.DataFrame(np.random.randn(4,3),columns=list('xyz'),index=list('ab...: cd'))In [16]: f=lambda x:'%.2f'%xIn [17]: df.applymap(f) Out[17]: x y z a 0.33 1.56 -1.21 b 1.18 2.26 -2.17 c 0.59 -0.59 -0.26 d -0.43 -0.41 -1.09

map,Series的應(yīng)用函數(shù)

之所以用applymap,因?yàn)镾eries也有一個應(yīng)用函數(shù)map方法

In [19]: df['x'].map(f) Out[19]: a 0.33 b 1.18 c 0.59 d -0.43 Name: x, dtype: object

排序和排名

sort_index,根據(jù)索引排序,值也會跟著索引移動,數(shù)據(jù)默認(rèn)是按行升序排列,參數(shù)axis設(shè)置軸向,ascending設(shè)置升/降序

In [20]: df=pd.DataFrame(np.random.randn(4,3),columns=list('xyz'),index=list('cd...: ab'))In [21]: df Out[21]: x y z c 0.574269 1.004828 -1.653797 d -1.153132 -2.733118 0.119374 a -1.616412 -1.232352 -0.053378 b 0.882328 -0.613165 2.238244In [22]: df.sort_index() Out[22]: x y z a -1.616412 -1.232352 -0.053378 b 0.882328 -0.613165 2.238244 c 0.574269 1.004828 -1.653797 d -1.153132 -2.733118 0.119374

sort_index如果需要根據(jù)某一列的值進(jìn)行排序,將列名傳參給by參數(shù)即可,數(shù)據(jù)結(jié)構(gòu)單個列字符串,多個列是列表

In [28]: df Out[28]: x y z c 0.574269 1.004828 -1.653797 d -1.153132 -2.733118 0.119374 a -1.616412 -1.232352 -0.053378 b 0.882328 -0.613165 2.238244In [29]: df.sort_index(by='x') /home/zelin/anaconda3/bin/ipython:1: FutureWarning: by argument to sort_index is deprecated, please use .sort_values(by=...)#!/home/zelin/anaconda3/bin/python Out[29]: x y z a -1.616412 -1.232352 -0.053378 d -1.153132 -2.733118 0.119374 c 0.574269 1.004828 -1.653797 b 0.882328 -0.613165 2.238244In [30]: df.sort_index(by=['x','z']) /home/zelin/anaconda3/bin/ipython:1: FutureWarning: by argument to sort_index is deprecated, please use .sort_values(by=...)#!/home/zelin/anaconda3/bin/python Out[30]: x y z a -1.616412 -1.232352 -0.053378 d -1.153132 -2.733118 0.119374 c 0.574269 1.004828 -1.653797 b 0.882328 -0.613165 2.238244

?

排名

排名和排序關(guān)系密切,且它會增設(shè)一個排名值(從1開始,一直到數(shù)組中有效數(shù)據(jù)的數(shù)量),它和numpy.argsort產(chǎn)生的間接排序索引差不多,只不過它可以破壞平級關(guān)系

rank

pandas對象的rank方法,為各組分配一個平均排名的方式破壞平級關(guān)系

In [32]: ser=pd.Series([7,-5,7,4,2,0,4])In [33]: ser Out[33]: 0 7 1 -5 2 7 3 4 4 2 5 0 6 4 dtype: int64In [34]: ser.rank() Out[34]: 0 6.5 1 1.0 2 6.5 3 4.5 4 3.0 5 2.0 6 4.5 dtype: float64

DataFrame可以在行或列上進(jìn)行排名

In [37]: df.rank() Out[37]: a b 0 3.0 1.0 1 2.0 3.0 2 1.0 2.0 3 4.0 4.0In [38]: df.rank(axis=1) Out[38]: a b 0 1.0 2.0 1 1.0 2.0 2 1.0 2.0 3 1.0 2.0

rank的破壞平級method選項

method說明
average默認(rèn):在相等分組中,為各個值分配平均排名
min使用整個分組的最小排名
max使用整個分組的最大排名
first按值在原始數(shù)據(jù)種的出現(xiàn)順序分配排名

?

帶由重復(fù)值的軸索引

某個索引值對應(yīng)多個值,則返回一個Series,而對應(yīng)單個值的,則返回一個標(biāo)量值

In [39]: ser=pd.Series([7,-5,7,4,2,0,4],index=['a','b','a','b','c','a','d'])In [40]: ser['a'] Out[40]: a 7 a 7 a 0 dtype: int64In [42]: ser['d'] Out[42]: 4

?

匯總和計算描述統(tǒng)計

pandas對象擁有一組常用的數(shù)學(xué)和統(tǒng)計方法,大部分屬于約簡和匯總統(tǒng)計

用于從Series中提取單個值(sum/mean等)或從DataFrame的行或列取一個Series,跟對應(yīng)的Numpy數(shù)組方法相比,他們都是基于沒有缺失數(shù)據(jù)的假設(shè)而構(gòu)建的

In [44]: df=pd.DataFrame([[1.4,np.nan],[7.1,-4.5],[np.nan,np.nan],[0.75,-1.3]],i...: ndex=list('abcd'),columns=['one','two'])In [45]: df Out[45]: one two a 1.40 NaN b 7.10 -4.5 c NaN NaN d 0.75 -1.3In [46]: df.sum() Out[46]: one 9.25 two -5.80 dtype: float64In [47]: df.sum(axis=1)#默認(rèn)等于0列相加,axis=1行相加 Out[47]: a 1.40 b 2.60 c 0.00 d -0.55 dtype: float64In [48]: df.sum(axis=1,skipna=False)#默認(rèn)排除NaN值,所以全NaN值則為0 Out[48]: a NaN b 2.60 c NaN d -0.55 dtype: float64

約簡方法的選項和方法

axisDataFrame的行用0,列用1
skipna排除缺失值,默認(rèn)值為True
level如果軸是層次化索引的(即MultilIndex),則根據(jù)level分組約簡

?

?

?

?

idxmin、idxmax達(dá)到最小值和最大值的索引,間接統(tǒng)計

In [51]: df.idxmax() Out[51]: one b two d dtype: object

?

另一些方法是累計型的:cumsum

In [53]: df Out[53]: one two a 1.40 NaN b 7.10 -4.5 c NaN NaN d 0.75 -1.3In [52]: df.cumsum() Out[52]: one two a 1.40 NaN b 8.50 -4.5 c NaN NaN d 9.25 -5.8

一次性匯總多個統(tǒng)計信息:describe(),數(shù)值型和非數(shù)值型產(chǎn)生不同匯總信息

In [53]: df1#數(shù)值型 Out[53]: one two a 1.40 NaN b 7.10 -4.5 c NaN NaN d 0.75 -1.3In [54]: df.describe() Out[54]: one two count 3.000000 2.000000 mean 3.083333 -2.900000 std 3.493685 2.262742 min 0.750000 -4.500000 25% 1.075000 -3.700000 50% 1.400000 -2.900000 75% 4.250000 -2.100000 max 7.100000 -1.300000In [56]: df2#非數(shù)值型 Out[56]: a b 1 aa aa 2 bb bbb 3 cc ddd 4 dd cccIn [57]: df.describe() Out[57]: a b count 4 4 unique 4 4 top bb ccc freq 1 1

描述和匯總統(tǒng)計

count非NA值的數(shù)量
describe針對Series或各DataFrame列計算匯總統(tǒng)計
min、max計算最小值和最大值
argmin、argmax計算能夠獲取到最小值和最大值的索引位置(整數(shù))
idxmin、inxmax計算能夠獲取到最小值和最大值的索引值
quantile計算樣本的分位數(shù)(0到1)
sum值的總和
mean值的平均數(shù)
median值的中位數(shù)
mad根據(jù)平均值計算平均絕對離差
var樣本值的方差
std樣本值的標(biāo)準(zhǔn)差
skew樣本值的偏度(三階矩)
kurt樣本值的峰度(四階矩)
cumsum樣本值的累計和
cummin、cummax樣本值的leis最小值和累計最大值
cumprod樣本值的累計積
diff計算一階差分(多用于時間序列)
pct_change計算百分?jǐn)?shù)變化
??

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

分組運(yùn)算:GroupBy技術(shù)

拆分--應(yīng)用--合并

In [1]: import pandas as pdIn [2]: import numpy as np #構(gòu)建DataFrame In [3]: df=pd.DataFrame({'key1':['a','a','b','b','a'],'key2':['one','two','one',...: 'two','one'],'data1':np.random.randn(5),'data2':np.random.randn(5)})In [4]: df Out[4]: key1 key2 data1 data2 0 a one -0.769863 0.321557 1 a two 0.163815 -0.635989 2 b one -1.048893 1.988060 3 b two -0.427548 0.322831 4 a one -1.115058 0.663252 #以鍵key1分組,獲取data1的GroupBy對象 In [5]: grouped=df['data1'].groupby(df['key1'])In [6]: grouped Out[6]: <pandas.core.groupby.groupby.SeriesGroupBy object at 0x7fd8664248d0> #GroupBy對象可以調(diào)用mean,sum等方法求平均值,和等值 In [7]: grouped.mean()#返回一個Series Out[7]: key1 a -0.573702 b -0.738221 Name: data1, dtype: float64

時間序列time series

時間序列是一種結(jié)構(gòu)化數(shù)據(jù)形式,在多個時間點(diǎn)觀測或測量到的任何事物都可以形成一段時間序列,時間序列數(shù)據(jù)的意義取決于具體的應(yīng)用場景,主要有以下幾種:

時間戳timestamp,特定的時刻 固定時期period,如2018全年 時間間隔interval,有起始和結(jié)束時間戳表示,時期period可以被看作間隔interval的特例 實(shí)驗(yàn)/過程時間,每個時間點(diǎn)都是相對于特定起始時間的一個度量,例如,從放入冰箱時起,每分鐘橙子的溫度

python標(biāo)準(zhǔn)庫包含用于日期date,時間time,日歷calendar的datetime,time,calendar模塊,datetime.datetime是用得最多的數(shù)據(jù)類型

詳情見python之時間格式(datetime,time,calendar),此處只舉例

In [47]: from datetime import datetime#datetime模塊的datetime類用的最多In [48]: import timeIn [49]: import calendarIn [50]: datetime.now()#返回一個時間元組 Out[50]: datetime.datetime(2018, 10, 19, 15, 47, 17, 175724)In [51]: time.time()#返回一個時間戳 Out[51]: 1539935328.026199In [52]: calendar.calendar(2013)#傳入年份,返回一個日歷表 Out[52]: ' 2013\n\n January February March\nMo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su\n 1 2 3 4 5 6 1 2 3 1 2 3\n 7 8 9 10 11 12 13 4 5 6 7 8 9 10 4 5 6 7 8 9 10\n14 15 16 17 18 19 20 11 12 13 14 15 16 17 11 12 13 14 15 16 17\n21 22 23 24 25 26 27 18 19 20 21 22 23 24 18 19 20 21 22 23 24\n28 29 30 31 25 26 27 28 25 26 27 28 29 30 31\n\n April May June\nMo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su\n 1 2 3 4 5 6 7 1 2 3 4 5 1 2\n 8 9 10 11 12 13 14 6 7 8 9 10 11 12 3 4 5 6 7 8 9\n15 16 17 18 19 20 21 13 14 15 16 17 18 19 10 11 12 13 14 15 16\n22 23 24 25 26 27 28 20 21 22 23 24 25 26 17 18 19 20 21 22 23\n29 30 27 28 29 30 31 24 25 26 27 28 29 30\n\n July August September\nMo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su\n 1 2 3 4 5 6 7 1 2 3 4 1\n 8 9 10 11 12 13 14 5 6 7 8 9 10 11 2 3 4 5 6 7 8\n15 16 17 18 19 20 21 12 13 14 15 16 17 18 9 10 11 12 13 14 15\n22 23 24 25 26 27 28 19 20 21 22 23 24 25 16 17 18 19 20 21 22\n29 30 31 26 27 28 29 30 31 23 24 25 26 27 28 29\n 30\n\n October November December\nMo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su\n 1 2 3 4 5 6 1 2 3 1\n 7 8 9 10 11 12 13 4 5 6 7 8 9 10 2 3 4 5 6 7 8\n14 15 16 17 18 19 20 11 12 13 14 15 16 17 9 10 11 12 13 14 15\n21 22 23 24 25 26 27 18 19 20 21 22 23 24 16 17 18 19 20 21 22\n28 29 30 31 25 26 27 28 29 30 23 24 25 26 27 28 29\n 30 31\n'

時間序列基礎(chǔ)

以時間為索引構(gòu)建Series序列

In [57]: from datetime import datetime #datetime傳入數(shù)字參數(shù),表示年,月,日,時,分,秒,年月日為必傳參數(shù),時分秒可選 In [62]: dates=[datetime(2018,10,19,10,0,0),datetime(2018,10,19,10,1,1),datetime...: (2018,10,19,10,2,2)]In [63]: s=pd.Series(np.random.randn(3),index=dates)In [64]: s Out[64]: 2018-10-19 10:00:00 2.450767 2018-10-19 10:01:01 -0.941043 2018-10-19 10:02:02 0.216157 dtype: float64 #這些datetime對象實(shí)際上是被放在列一個DatetimeIndex中,DatetimeIndex中的各個標(biāo)量值是pandas的Timestamp對象 In [68]: type(s) Out[68]: pandas.core.series.Series#--利用python進(jìn)行數(shù)據(jù)分析書中顯示為pandas.core.series.TimeSeries,與實(shí)際符,預(yù)計是新版本改變In [69]: s.index Out[69]: DatetimeIndex(['2018-10-19 10:00:00', '2018-10-19 10:01:01','2018-10-19 10:02:02'],dtype='datetime64[ns]', freq=None)

索引,選取,子集構(gòu)造

In [82]: dates=[datetime(2018,10,19,10,0,0),datetime(2018,10,19,10,1,1),datetime...: (2018,10,19,10,2,2),datetime(2018,10,19,10,3,3),datetime(2018,10,19,10,...: 4,4)]In [83]: s=pd.Series(np.random.randn(5),index=dates)In [84]: s Out[84]: 2018-10-19 10:00:00 0.879305 2018-10-19 10:01:01 1.218865 2018-10-19 10:02:02 -0.859521 2018-10-19 10:03:03 -1.272252 2018-10-19 10:04:04 0.200955 dtype: float64In [85]: stamp=s.index[2]In [86]: s[stamp] Out[86]: -0.8595210222802377#獲取到第三行的值#索引也可傳入一個可被解釋為日期的字符串 In [90]: s['20181019100202'] Out[90]: -0.8595210222802377In [92]: s['19/10/2018 10:02:02'] Out[92]: -0.8595210222802377 #當(dāng)傳入索引前相同部分的字符串,也可用作切片 In [93]: s['19/10/2018']時間字符串格式之一 Out[93]: 2018-10-19 10:00:00 0.879305 2018-10-19 10:01:01 1.218865 2018-10-19 10:02:02 -0.859521 2018-10-19 10:03:03 -1.272252 2018-10-19 10:04:04 0.200955 dtype: float64In [94]: s['20181019']#時間字符串格式之一 Out[94]: 2018-10-19 10:00:00 0.879305 2018-10-19 10:01:01 1.218865 2018-10-19 10:02:02 -0.859521 2018-10-19 10:03:03 -1.272252 2018-10-19 10:04:04 0.200955 dtype: float64#由于大部分時間序列數(shù)據(jù)都是按照時間先后排序的,因此也可以用不存在于該時間序類中的時間戳對其進(jìn)行切片(即范圍查詢) In [98]: s['19/10/2018 10:0:0':'19/10/2018 10:01:02'] Out[98]: 2018-10-19 10:00:00 0.879305 2018-10-19 10:01:01 1.218865 dtype: float64#實(shí)例方法truncate也能實(shí)現(xiàn)截取兩個日期時間的Series,所選范圍為閉端,即包含所穿參數(shù) In [105]: s.truncate(after='20181019100303',before='20181019100000') Out[105]: 2018-10-19 10:00:00 0.879305 2018-10-19 10:01:01 1.218865 2018-10-19 10:02:02 -0.859521 2018-10-19 10:03:03 -1.272252 dtype: float64

帶有重復(fù)索引的時間序列

#當(dāng)索引為不重復(fù)項時,返回標(biāo)量值,當(dāng)索引為重復(fù)項時,返回Series序列 In [109]: s['20181001'] Out[109]: 2018-10-01 -1.217149 2018-10-01 -1.714301 dtype: float64In [113]: s['20181003'] Out[113]: 0.14757289913298496

注意:datetime不能傳入01,02等0開頭的參數(shù),會報錯

In [122]: dates=[datetime(2011,01,02),datetime(2011,01,05),datetime(2011,01,07),...: datetime(2011,01,08),datetime(2011,01,10),datetime(2011,01,12)]File "<ipython-input-122-98aa28d7950b>", line 1dates=[datetime(2011,01,02),datetime(2011,01,05),datetime(2011,01,07),datetime(2011,01,08),datetime(2011,01,10),datetime(2011,01,12)]^ SyntaxError: invalid tokenIn [123]: dates=[datetime(2011,1,2),datetime(2011,1,5),datetime(2011,1,7),dateti...: me(2011,1,8),datetime(2011,1,10),datetime(2011,1,12)]

生成日期范圍

#pandas.date_range可用于指定長度的DatetimeIndex,默認(rèn)情況下,產(chǎn)生按天計算的時間點(diǎn),date_range默認(rèn)保留起始和結(jié)束日期,即閉端 In [139]: index=pd.date_range('4/1/2018','4/10/2018')#月日年In [140]: s=pd.Series(np.random.randn(10),index=index)In [141]: s Out[141]: 2018-04-01 -0.667058 2018-04-02 1.781576 2018-04-03 -0.845532 2018-04-04 -1.121527 2018-04-05 0.572054 2018-04-06 -0.120728 2018-04-07 1.396313 2018-04-08 1.559138 2018-04-09 0.737590 2018-04-10 1.905737 Freq: D, dtype: float64 #如果給參數(shù)period傳入一個表示索引個數(shù)的數(shù)字,可以設(shè)定索引間隔時間,即時間差/periods In [149]: index=pd.date_range(start='4/1/2018',end='4/10/2018',periods=5)#表示間隔兩天,產(chǎn)生5個索引,即5等分時間差I(lǐng)n [150]: s=pd.Series(np.random.randn(5),index=index)In [151]: s Out[151]: 2018-04-01 00:00:00 -1.440547 2018-04-03 06:00:00 0.295920 2018-04-05 12:00:00 0.297291 2018-04-07 18:00:00 -0.753377 2018-04-10 00:00:00 1.643616 dtype: float64 #如果希望產(chǎn)生一組被規(guī)范化到午夜的時間戳,normalize參數(shù)可實(shí)現(xiàn)該功能,即忽略時間,從開始日期的零點(diǎn)始,結(jié)束日期的零點(diǎn)終 In [155]: index=pd.date_range(start='4/1/2018 08:04:22',end='4/10/2018 12:12:21'...: ,periods=5)In [156]: index=pd.date_range(start='4/1/2018',end='4/10/2018',periods=5,normali...: ze=True)In [157]: s=pd.Series(np.random.randn(5),index=index)In [158]: s Out[158]: 2018-04-01 00:00:00 1.209585 2018-04-03 06:00:00 -1.129351 2018-04-05 12:00:00 -1.488379 2018-04-07 18:00:00 -0.882576 2018-04-10 00:00:00 -0.152073 dtype: float64

頻率和基礎(chǔ)偏移量

pandas中的頻率是由一個基礎(chǔ)頻率(hbase frequency)和一個乘數(shù)組成的,基礎(chǔ)頻率通常以一個字符串別名表示,比如'M'表示月,'H'表示小時,對于每個基礎(chǔ)頻率,都有一個被稱為日期偏移量(date offset)的對象與之對應(yīng)

In [159]: from pandas.tseries.offsets import Hour,Minute In [160]: hour=Hour()#基礎(chǔ)頻率 In [161]: hour Out[161]: <Hour>In [162]: four_hours=Hour(4)#導(dǎo)入一個整數(shù)即可定義偏移量的倍數(shù)In [163]: four_hours Out[163]: <4 * Hours>#一般無需顯式創(chuàng)建這樣的對象,在date_range函數(shù)前傳入?yún)?shù)freq,參數(shù)值使用諸如'h','4h'這樣的字符串別名的整數(shù)倍 In [164]: dates=pd.date_range('20181211','20181220',freq='2d')#字符串別名不區(qū)分大小寫In [165]: s=pd.Series(np.random.randn(5),index=dates)In [166]: s Out[166]: 2018-12-11 -0.031886 2018-12-13 0.827174 2018-12-15 0.317349 2018-12-17 -1.938784 2018-12-19 -0.410817 Freq: 2D, dtype: float64#也可以傳入頻率字符串:如'4h30min',這種字符串可以被高效的解析為等效的表達(dá)式In [168]: dates=pd.date_range('20181211','20181220',freq='2d48h') In [170]: s=pd.Series(np.random.randn(3),index=dates)In [171]: s Out[171]: 2018-12-11 -1.380608 2018-12-15 -0.012547 2018-12-19 -0.858346 Freq: 4D, dtype: float64#大部分偏移量對象都可以用'+'加號連接 In [167]: Hour(2)+Minute(30) Out[167]: <150 * Minutes>

時間序列的常見基礎(chǔ)頻率表

注意:有些頻率描述的時間點(diǎn)不是均勻分隔的,如‘M’日里月末和’BM’每月最后一個工作日,對于前者,就取決于每月的天數(shù),對于后者,還要考慮月末是不是周末,我們稱這些為錨點(diǎn)偏移量

別名偏移量類型說明
DDay每日歷日
BBussinessDay每工作日
HHour每小時
T/minMinute每分
SSecond每秒
L/msMilli每毫秒(即千分之一秒)
UMicro每微秒(即每百萬分之一秒)
MMonthEnd每月最后一個日歷日
BMBusinessMonthEnd每月最后一個工作日
MSMonthBegin每月第一個日歷日
BMSBusinessMonthBegin每月第一個工作日
W-MON,W-TUE....Week從指定的星期幾開始計算
WOM-1MON,WOM-2MON...?從指定的每月第一,第二...周的星期即,例如:WOM-3FRI表示每月的第三隔星期五
A-JAN,A-FEBYearEnd每年指定月份的最后一個日歷日
BA-JAN,BA-FEBBusinessYearEnd每年指定月份的最后一個工作日
AS-JAN,AS-FEBYearBegin每年指定月份的第一個日歷日
BAS-JAN,BAS-FEBBusinessYearBegin每年指定月份的第一個工作日

WOM日期

WOM(Week Of Month)是一種非常使用的頻率類,它以WOM開頭,它使你能獲得'每月第3隔星期五'之類的日期

In [172]: rng=pd.date_range('1/1/2018','9/1/2018',freq='WOM-3FRI')In [173]: list(rng) Out[173]: [Timestamp('2018-01-19 00:00:00', freq='WOM-3FRI'),Timestamp('2018-02-16 00:00:00', freq='WOM-3FRI'),Timestamp('2018-03-16 00:00:00', freq='WOM-3FRI'),Timestamp('2018-04-20 00:00:00', freq='WOM-3FRI'),Timestamp('2018-05-18 00:00:00', freq='WOM-3FRI'),Timestamp('2018-06-15 00:00:00', freq='WOM-3FRI'),Timestamp('2018-07-20 00:00:00', freq='WOM-3FRI'),Timestamp('2018-08-17 00:00:00', freq='WOM-3FRI')]

移動(超前或滯后)數(shù)據(jù)

移動(shifting)指的是沿著時間軸將數(shù)據(jù)前移或者后移,但保持索引不變

In [4]: ts=pd.Series(np.random.randn(4),index=pd.date_range('1/1/2018',periods=4...: ,freq='M')) #periods=4表示以1/1/2018為起始日期產(chǎn)生4個時間索引,間隔為月,即freq='M' In [5]: ts Out[5]: 2018-01-31 0.467078 2018-02-28 -0.664430 2018-03-31 -0.823731 2018-04-30 2.407555 Freq: M, dtype: float64In [14]: ts.shift(2)#正整數(shù)向下移 Out[14]: 2018-01-31 NaN 2018-02-28 NaN 2018-03-31 0.467078 2018-04-30 -0.664430 Freq: M, dtype: float64In [15]: ts.shift(-2)#負(fù)整數(shù)向上移動 Out[15]: 2018-01-31 -0.823731 2018-02-28 2.407555 2018-03-31 NaN 2018-04-30 NaN Freq: M, dtype: float64#shift通常用于計算一個時間序列或多個時間序列中的百分比變化,可以這樣表達(dá): ts/ts.shift(1)-1 #由于單純的位移操作不會修改索引,所以部分?jǐn)?shù)據(jù)會被丟棄,因此如果頻率已知,則可以將頻率freq傳給shift以便實(shí)現(xiàn)移動時間戳進(jìn)行位移,而不是移動數(shù)據(jù): In [17]: ts.shift(2,freq='M') Out[17]: 2018-03-31 0.467078 2018-04-30 -0.664430 2018-05-31 -0.823731 2018-06-30 2.407555 Freq: M, dtype: float64 #還可以使用其他頻率,于是就能非常靈活地對數(shù)據(jù)進(jìn)行超前或滯后處理了 In [21]: ts.shift(1,'3d') Out[21]: 2018-02-03 0.467078 2018-03-03 -0.664430 2018-04-03 -0.823731 2018-05-03 2.407555 dtype: float64In [22]: ts.shift(3,'d') Out[22]: 2018-02-03 0.467078 2018-03-03 -0.664430 2018-04-03 -0.823731 2018-05-03 2.407555 dtype: float64

通過偏移量對日期進(jìn)行位移

pandas的日期偏移量還可以用在datetime和Timestamp對象上

In [25]: from pandas.tseries.offsets import Day,MonthEnd In [26]: now=datetime(2011,11,7)In [27]: now+3*Day() Out[27]: Timestamp('2011-11-10 00:00:00') #如果加的是錨點(diǎn)偏移量,第一次增量會將原日期向前滾動到符合頻率規(guī)則的下一個日期,比如第一次位移的量可能沒有一個月那么長,就在當(dāng)月 In [26]: now=datetime(2011,11,7)In [27]: now+3*Day() Out[27]: Timestamp('2011-11-10 00:00:00')In [28]: now+MonthEnd() Out[28]: Timestamp('2011-11-30 00:00:00')In [29]: now+2*MonthEnd() Out[29]: Timestamp('2011-12-31 00:00:00')In [30]: now+MonthEnd(2) Out[30]: Timestamp('2011-12-31 00:00:00') #通過錨點(diǎn)偏移量的rollforward和rollback方法,可以顯式的將日期前移或向后滾動 In [31]: offset=MonthEnd()In [32]: offset.rollforward(now)#向前翻滾就是本月 Out[32]: Timestamp('2011-11-30 00:00:00') In [33]: offset.rollback(now)#前后翻滾就是上一個月 Out[33]: Timestamp('2011-10-31 00:00:00') #結(jié)合groupby使用前后滾動 In [34]: ts=pd.Series(np.random.randn(20),index=pd.date_range('1/15/2018',period...: s=20,freq='4d'))In [35]: ts Out[35]: 2018-01-15 -1.123869 2018-01-19 0.691454 2018-01-23 -1.492071 2018-01-27 0.047393 2018-01-31 0.190645 2018-02-04 -1.427506 2018-02-08 0.318326 2018-02-12 -0.073011 2018-02-16 0.636296 2018-02-20 -0.570525 2018-02-24 -0.865244 2018-02-28 -0.356154 2018-03-04 -0.247588 2018-03-08 0.589253 2018-03-12 1.113633 2018-03-16 1.722783 2018-03-20 -2.332676 2018-03-24 -0.275168 2018-03-28 -0.171739 2018-04-01 -0.369748 Freq: 4D, dtype: float64In [36]: ts.groupby(offset.rollforward).mean()#全部轉(zhuǎn)換為幾類相同日期,然后分類 Out[36]: 2018-01-31 -0.337290 2018-02-28 -0.333974 2018-03-31 0.056928 2018-04-30 -0.369748 dtype: float64 #結(jié)合groupby函數(shù)使用滾動的封裝方法:resample In [38]: ts.resample('M',how='mean')#python2 /usr/bin/ipython3:1: FutureWarning: how in .resample() is deprecated the new syntax is .resample(...).mean()#! /bin/sh Out[38]: 2018-01-31 -0.337290 2018-02-28 -0.333974 2018-03-31 0.056928 2018-04-30 -0.369748 Freq: M, dtype: float64 #結(jié)合groupby函數(shù)使用滾動的封裝方法:resampleIn [39]: ts.resample('M').mean()#python3 Out[39]: 2018-01-31 -0.337290 2018-02-28 -0.333974 2018-03-31 0.056928 2018-04-30 -0.369748 Freq: M, dtype: float64

時區(qū)處理

時區(qū)信息來自python庫pytz,它使python可以使用Olso數(shù)據(jù)庫(匯編了世界時區(qū)信息),由于pandas包裝了pytz的功能,因此可以不用記其API,只要記住時區(qū)名即可,時區(qū)名可以在文檔中找到,也可以通過交互查看

In [42]: import pytz#時區(qū)信息庫 In [43]: pytz.timezone('US/Eastern')#獲取時區(qū)信息, Out[43]: <DstTzInfo 'US/Eastern' LMT-1 day, 19:04:00 STD> In [48]: pytz.common_timezones[1]#時區(qū)名稱列表 Out[48]: 'Africa/Accra'

本地化和轉(zhuǎn)換

默認(rèn)情況下,pandas中的時間序列是單純的(naive)時區(qū),其索引的tz字段為None,在生成日期范圍的時候還可以加上一個時區(qū)集,從單純到本地化的轉(zhuǎn)換是通過tz_locallize方法處理的:

In [56]: rng=pd.date_range('3/9/2018 9:30',periods=6,freq='D')In [57]: ts=pd.Series(np.random.randn(len(rng)),index=rng)In [58]: ts Out[58]: 2018-03-09 09:30:00 -1.470021 2018-03-10 09:30:00 -1.171575 2018-03-11 09:30:00 0.739337 2018-03-12 09:30:00 -0.990569 2018-03-13 09:30:00 0.007370 2018-03-14 09:30:00 0.389544 Freq: D, dtype: float64In [62]: rng.tzIn [63]: #返回值為空In [52]: ts1=pd.date_range('3/9/2018 9:30',periods=10,freq='D',tz='UTC') Out[52]: DatetimeIndex(['2018-03-09 09:30:00+00:00', '2018-03-10 09:30:00+00:00','2018-03-11 09:30:00+00:00', '2018-03-12 09:30:00+00:00','2018-03-13 09:30:00+00:00', '2018-03-14 09:30:00+00:00','2018-03-15 09:30:00+00:00', '2018-03-16 09:30:00+00:00','2018-03-17 09:30:00+00:00', '2018-03-18 09:30:00+00:00'],dtype='datetime64[ns, UTC]', freq='D') In [55]: ts1.tz#默認(rèn)tz屬性為None Out[55]: <UTC> In [65]: ts_utc=ts.tz_localize('UTC') #使用tz_localize轉(zhuǎn)換為UTC本地時區(qū) In [66]: ts_utc Out[66]: 2018-03-09 09:30:00+00:00 -1.470021 2018-03-10 09:30:00+00:00 -1.171575 2018-03-11 09:30:00+00:00 0.739337 2018-03-12 09:30:00+00:00 -0.990569 2018-03-13 09:30:00+00:00 0.007370 2018-03-14 09:30:00+00:00 0.389544 Freq: D, dtype: float64#當(dāng)時間序列被本地化到某個特定時區(qū),就可以用tz_convert將其轉(zhuǎn)換為別的時區(qū)了In [67]: ts_utc.tz_convert('US/Eastern') Out[67]: 2018-03-09 04:30:00-05:00 -1.470021 2018-03-10 04:30:00-05:00 -1.171575 2018-03-11 05:30:00-04:00 0.739337 2018-03-12 05:30:00-04:00 -0.990569 2018-03-13 05:30:00-04:00 0.007370 2018-03-14 05:30:00-04:00 0.389544 Freq: D, dtype: float64 #tz_localize和tz_convert是DatetimeIndex的實(shí)例方法,對于單純時間戳的本地化操作還會檢查夏令時轉(zhuǎn)變期附近容易混淆或不存在的時間

操作時區(qū)意識型Timestamp對象

跟時間序列和日期范圍差不多,Timestamp對象也能被從單純型(naive)本地化為時區(qū)意識型(time zone-aware),并從一個時區(qū)轉(zhuǎn)換為另一個時區(qū)

#單純時區(qū)和本地時區(qū)之間可以靈活轉(zhuǎn)換 In [70]: stamp=pd.Timestamp('2011-03-12 04:00')#創(chuàng)建TimestampIn [71]: stamp Out[71]: Timestamp('2011-03-12 04:00:00')In [72]: stamp_utc=stamp.tz_localize('utc')In [73]: stamp_utc Out[73]: Timestamp('2011-03-12 04:00:00+0000', tz='UTC')In [75]: stamp_utc.tz_convert('US/Eastern') Out[75]: Timestamp('2011-03-11 23:00:00-0500', tz='US/Eastern') #創(chuàng)建Timestamp時,還可以傳入一個時區(qū)信息 In [76]: stamp_moscow=pd.Timestamp('2011-01-12 04:00',tz='Europe/Moscow')In [77]: stamp_moscow Out[77]: Timestamp('2011-01-12 04:00:00+0300', tz='Europe/Moscow')

時區(qū)意識型Timestamp對象在內(nèi)部保存了一個UTC時間戳(自UNIX紀(jì)元(1970年1月1日0時)算起的納秒數(shù))。這個UTC值在時區(qū)轉(zhuǎn)換過程中是不會發(fā)生變化的

In [76]: stamp_moscow=pd.Timestamp('2011-01-12 04:00',tz='Europe/Moscow')In [77]: stamp_moscow Out[77]: Timestamp('2011-01-12 04:00:00+0300', tz='Europe/Moscow')In [78]: stamp_utc.value Out[78]: 1299902400000000000In [79]: stamp_utc.tz_convert('US/Eastern').value Out[79]: 1299902400000000000

當(dāng)使用pandas的DateOffset對象執(zhí)行時間算術(shù)運(yùn)算時,運(yùn)算過程會自動關(guān)注是否存在夏令時轉(zhuǎn)變期

#夏令時轉(zhuǎn)變前30分鐘--沒有區(qū)別 In [80]: from pandas.tseries.offsets import HourIn [81]: stamp=pd.Timestamp('2012-03-12 01:30',tz='US/Eastern')In [82]: stamp+Hour() Out[82]: Timestamp('2012-03-12 02:30:00-0400', tz='US/Eastern')In [83]: stamp Out[83]: Timestamp('2012-03-12 01:30:00-0400', tz='US/Eastern') #夏令時轉(zhuǎn)變前90分鐘--少了一個小時,why? In [84]: stamp=pd.Timestamp('2012-11-04 00:30',tz='US/Eastern')In [85]: stamp Out[85]: Timestamp('2012-11-04 00:30:00-0400', tz='US/Eastern')In [86]: stamp+2*Hour() Out[86]: Timestamp('2012-11-04 01:30:00-0500', tz='US/Eastern')

不同時區(qū)之間的運(yùn)算

如果兩個時間序列的時區(qū)不同,在將他們合并到一起時,最終結(jié)果就會是UTC,由于時間戳其實(shí)是以UTC存儲的,所以并不需要發(fā)生任何轉(zhuǎn)換

In [87]: rng=pd.date_range('3/7/2012 9:30',periods=10,freq='B')In [88]: ts=pd.Series(np.random.randn(10),index=rng)In [89]: ts Out[89]: 2012-03-07 09:30:00 1.946924 2012-03-08 09:30:00 0.305003 2012-03-09 09:30:00 0.529779 2012-03-12 09:30:00 -1.501415 2012-03-13 09:30:00 -0.837557 2012-03-14 09:30:00 0.529487 2012-03-15 09:30:00 0.055145 2012-03-16 09:30:00 -0.746819 2012-03-19 09:30:00 -0.824349 2012-03-20 09:30:00 0.627202 Freq: B, dtype: float64In [90]: ts1=ts[:7].tz_localize('Europe/London')In [91]: ts2=ts[2:].tz_localize('Europe/Moscow')In [92]: ts1 Out[92]: 2012-03-07 09:30:00+00:00 1.946924 2012-03-08 09:30:00+00:00 0.305003 2012-03-09 09:30:00+00:00 0.529779 2012-03-12 09:30:00+00:00 -1.501415 2012-03-13 09:30:00+00:00 -0.837557 2012-03-14 09:30:00+00:00 0.529487 2012-03-15 09:30:00+00:00 0.055145 Freq: B, dtype: float64In [93]: ts2 Out[93]: 2012-03-09 09:30:00+04:00 0.529779 2012-03-12 09:30:00+04:00 -1.501415 2012-03-13 09:30:00+04:00 -0.837557 2012-03-14 09:30:00+04:00 0.529487 2012-03-15 09:30:00+04:00 0.055145 2012-03-16 09:30:00+04:00 -0.746819 2012-03-19 09:30:00+04:00 -0.824349 2012-03-20 09:30:00+04:00 0.627202 Freq: B, dtype: float64In [94]: ts1+ts2#為什么是NaN值????????? Out[94]: 2012-03-07 09:30:00+00:00 NaN 2012-03-08 09:30:00+00:00 NaN 2012-03-09 05:30:00+00:00 NaN 2012-03-09 09:30:00+00:00 NaN 2012-03-12 05:30:00+00:00 NaN 2012-03-12 09:30:00+00:00 NaN 2012-03-13 05:30:00+00:00 NaN 2012-03-13 09:30:00+00:00 NaN 2012-03-14 05:30:00+00:00 NaN 2012-03-14 09:30:00+00:00 NaN 2012-03-15 05:30:00+00:00 NaN 2012-03-15 09:30:00+00:00 NaN 2012-03-16 05:30:00+00:00 NaN 2012-03-19 05:30:00+00:00 NaN 2012-03-20 05:30:00+00:00 NaN dtype: float64

?

?

?

?

?

?

?

三 matplotlib模塊

matplotlib是一個用于創(chuàng)建出版質(zhì)量圖表的桌面繪圖包(主要是2D方面),其目的是為python構(gòu)建一個MATLAB式的繪圖接口,它不僅支持各種操作系統(tǒng)上許多不同的GUI后端,而且還能將圖片導(dǎo)出為各種常見的矢量(vector)和光柵(raster)圖

標(biāo)PDF JPG什么的

先來看一個使用制圖小例子

>>> import matplotlib.pyplot as plt >>> x=np.linspace(0,10,1000) >>> y=np.sin(x) >>> y=np.sin(x)+1 >>> z=np.cos(x**2)+1 >>> plt.plot(x,y,label='$\sin x+1$',color='red',linewidth=2) [<matplotlib.lines.Line2D object at 0x08CEB350>] >>> plt.figure(figsize=(8,4)) <Figure size 800x400 with 0 Axes> >>> plt.plot(x,z,'b--',label='$\cos x^2+1$') [<matplotlib.lines.Line2D object at 0x0A78FBF0>] >>> plt.xlabel('time(s)') Text(0.5, 0, 'time(s)') >>> plt.ylabel('volt') Text(0, 0.5, 'volt') >>> plt.title('example') Text(0.5, 1.0, 'example') >>> plt.ylim(0,2.2) (0, 2.2) >>> plt.legend() <matplotlib.legend.Legend object at 0x0A786610> >>> plt.show() ''' 安裝matplotlib,需要使用apt-get安裝依賴包(不是用pip3安裝) sudo apt-get install python3-tk pip3 install matplotlib '''>>> import matplotlib >>> import matplotlib.pyplot as plt >>> fg=plt.figure() >>> ax1=fg.add_subplot(2,2,1) >>> ax2=fg.add_subplot(2,2,2) >>> ax3=fg.add_subplot(2,2,3 ... ) >>> plt.gcf() <Figure size 640x480 with 3 Axes> >>> plt.show()

四? ? scipy模塊

Numpy提供了多維數(shù)組功能,但它只是一般的數(shù)組,并不是矩陣,例如,當(dāng)兩個數(shù)組相乘時,只是對應(yīng)元素相乘,而不是矩陣乘法,scipy提供了真正的矩陣,以及大量基于矩陣預(yù)算的對象和函數(shù),但是scipy是依賴于numpy庫的,numpy還是基礎(chǔ)庫

Scipy包含的功能有最優(yōu)化、線性代數(shù)、積分、插值、擬合、特殊函數(shù)、快速傅里葉變換、信號處理和圖像處理、常微分方程求解和其他科學(xué)與工程中常用的計算

#-*- coding:utf-8 -*- #求解非線性方程組2x1-x2^2=1,x1^2-x2=2 from scipy.optimize import fsolve #導(dǎo)入求解方程組的函數(shù) def f(x): #定義需要求解的方程組x1=x[0]x2=x[1]return [2*x1-x2**2-1,x1**2-x2-2] result=fsolve(f,[1,1]) #輸入初值[1,1]并求解 print(result)#數(shù)值積分 from scipy import integrate #導(dǎo)入積分函數(shù) def g(x): #定義被積函數(shù)return (1-x**2)**0.5 pi_2,err=integrate.quad(g,-1,1) #積分結(jié)果和誤差 print(pi_2*2) #由微積分知識知道積分結(jié)果為圓周率pi的一半

?

?

?

?

?

?

?

?

?

?

?

?

?

總結(jié)

以上是生活随笔為你收集整理的利用python进行数据分析_从删库到跑路的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。