pandas(panel data)是 Python 中用于數(shù)據(jù)分析的王牌庫(kù)止剖,pandas 是基于 numpy 構(gòu)建的凸舵,所以 pandas 也是一個(gè)開(kāi)源的 Python 第三方庫(kù)前塔。它被廣泛應(yīng)用于機(jī)器學(xué)習(xí)前期的數(shù)據(jù)清洗工作中情龄,非常簡(jiǎn)單且強(qiáng)大牙丽。如果把 numpy 看作是 Python 中 List 的加強(qiáng)版膳算,那么 pandas 可以認(rèn)為是 Python 中 Dictionary 的加強(qiáng)版。另外石景,pandas 最初是作為金融數(shù)據(jù)分析工具而被開(kāi)發(fā)出來(lái)劈猿,所以 pandas 天生就具備時(shí)間序列分析的基因。
pandas 的常用數(shù)據(jù)結(jié)構(gòu)主要有以下4種:
-
Series 是一種一維數(shù)組潮孽,和 numpy 里的數(shù)組很像揪荣。和 numpy 中數(shù)組不同的地方是,pandas 的 Series 能為數(shù)據(jù)自定義標(biāo)簽往史,也就是索引仗颈,并通過(guò)索引來(lái)訪問(wèn)數(shù)組中的數(shù)據(jù),在
series1 = pd.Series(data, index)
中椎例,如果省略了 index挨决,pandas 會(huì)默認(rèn)用角標(biāo)[0,……,len(data)-1]
進(jìn)行索引。 - Time-Series 是以時(shí)間為索引的 Series订歪。
- DataFrame 二維的表格型數(shù)據(jù)結(jié)構(gòu)脖祈,像 Python 中的 Excel∷⒔可以將 DataFrame 理解為 Series 的容器盖高,我們工作中遇到的數(shù)據(jù)大部分是以二維表格的形式出現(xiàn)。
- Panel 三維數(shù)組眼虱,可以理解為 DataFrame 的容器喻奥。
本篇我們依舊采用 Anaconda 中的 jupyter notebook 演示:
首先我們用 pandas 庫(kù)創(chuàng)建一個(gè) Series:
In [1]: import pandas as pd
import numpy as np
a = pd.Series([1,2,3,4,np.nan])
print(a)
Out [1]: 0 1.0
1 2.0
2 3.0
3 4.0
4 NaN
dtype: float64
采用 date_range
函數(shù)可以遍歷時(shí)間,以天為周期:
In [2]: dates = pd.date_range('20190501',periods=6)
print(dates)
Out [2]: DatetimeIndex(['2019-05-01', '2019-05-02', '2019-05-03', '2019-05-04',
'2019-05-05', '2019-05-06'],
dtype='datetime64[ns]', freq='D')
定義一個(gè)矩陣捏悬,即 pandas 中的 DataFrame撞蚕,指定行名稱和列名稱,并用隨機(jī)數(shù)字填充矩陣:
In [3]: #定義了6行4列的矩陣过牙,用 date 為索引甥厦,并賦列名
df = pd.DataFrame(np.random.randn(6,4),index=dates,columns=['a','b','c','d'])
print(df)
Out [3]: a b c d
2019-05-01 -1.445846 1.011859 0.838892 0.309828
2019-05-02 -0.564464 0.158810 0.785483 -0.498693
2019-05-03 -1.011108 0.306535 0.196237 -0.547271
2019-05-04 0.017039 -0.077461 -0.391788 0.815798
2019-05-05 -1.595324 0.347070 -1.613977 -1.350416
2019-05-06 -0.402783 -0.742630 0.839047 -0.605392
我們可以獲得 DataFrame 的 index、columns 和 values:
In [4]: print(df.index)
print(df.columns)
print(df.values)
Out [4]: DatetimeIndex(['2019-05-01', '2019-05-02', '2019-05-03', '2019-05-04',
'2019-05-05', '2019-05-06'],
dtype='datetime64[ns]', freq='D')
Index(['a', 'b', 'c', 'd'], dtype='object')
[[-1.44584558 1.01185859 0.83889211 0.30982824]
[-0.56446367 0.1588099 0.78548279 -0.49869251]
[-1.01110805 0.30653486 0.19623705 -0.54727079]
[ 0.01703866 -0.07746057 -0.39178791 0.81579809]
[-1.59532439 0.3470701 -1.61397711 -1.35041627]
[-0.40278298 -0.74263036 0.83904703 -0.60539198]]
describe
函數(shù)可以得到一個(gè) DataFrame 的描述寇钉,例如均值矫渔,和等常見(jiàn)的統(tǒng)計(jì)量:
In [5]: print(df.describe())
Out [5]: a b c d
count 6.000000 6.000000 6.000000 6.000000
mean -0.833748 0.167364 0.108982 -0.312691
std 0.627408 0.574967 0.974719 0.763307
min -1.595324 -0.742630 -1.613977 -1.350416
25% -1.337161 -0.018393 -0.244782 -0.590862
50% -0.787786 0.232672 0.490860 -0.522982
75% -0.443203 0.336936 0.825540 0.107698
max 0.017039 1.011859 0.839047 0.815798
同樣,也可以對(duì) DataFrame 進(jìn)行轉(zhuǎn)置操作:
In [6]: print(df.T)
Out [6]: 2019-05-01 2019-05-02 2019-05-03 2019-05-04 2019-05-05 2019-05-06
a -1.445846 -0.564464 -1.011108 0.017039 -1.595324 -0.402783
b 1.011859 0.158810 0.306535 -0.077461 0.347070 -0.742630
c 0.838892 0.785483 0.196237 -0.391788 -1.613977 0.839047
d 0.309828 -0.498693 -0.547271 0.815798 -1.350416 -0.605392
可以根據(jù)某一列對(duì) DataFrame 進(jìn)行排序:
In [7]: print(df.sort_values(by="d")) # 根據(jù) d 列對(duì) DataFrame 進(jìn)行排序摧莽,默認(rèn)升序
Out [7]: a b c d
2019-05-05 -1.595324 0.347070 -1.613977 -1.350416
2019-05-06 -0.402783 -0.742630 0.839047 -0.605392
2019-05-03 -1.011108 0.306535 0.196237 -0.547271
2019-05-02 -0.564464 0.158810 0.785483 -0.498693
2019-05-01 -1.445846 1.011859 0.838892 0.309828
2019-05-04 0.017039 -0.077461 -0.391788 0.815798
將 numpy 中的矩陣轉(zhuǎn)成 pandas 中的 DataFrame:
In [8]: df1 = pd.DataFrame(np.arange(12).reshape(3,4)) # 索引和列名默認(rèn)為元素角標(biāo)位置
print(df1)
Out [8]: 0 1 2 3
0 0 1 2 3
1 4 5 6 7
2 8 9 10 11
將 numpy 中的矩陣轉(zhuǎn)成 pandas 中的 DataFrame庙洼,并指定索引和列名:
In [9]: df2 = pd.DataFrame(np.arange(24).reshape(6,4),index=dates,columns=['a','b','c','d'])
print(df2)
Out [9]: a b c d
2019-05-01 0 1 2 3
2019-05-02 4 5 6 7
2019-05-03 8 9 10 11
2019-05-04 12 13 14 15
2019-05-05 16 17 18 19
2019-05-06 20 21 22 23
選出 DataFrame 中某一列的元素:
In [10]: print(df2['a']) # 另一種方法 print(df2.a)
Out [10]: 2019-05-01 0
2019-05-02 4
2019-05-03 8
2019-05-04 12
2019-05-05 16
2019-05-06 20
Freq: D, Name: a, dtype: int64
選出 DataFrame 中的前 n 行數(shù)據(jù):
In [11]: print(df2[0:3]) # 另一種方法 print(df2['2019-05-01':'2019-05-03'])
Out [11]: a b c d
2019-05-01 0 1 2 3
2019-05-02 4 5 6 7
2019-05-03 8 9 10 11
選擇 DataFrame 的一個(gè)連續(xù)數(shù)據(jù)區(qū)域:
In [12]: print(df2.iloc[3:5,1:3]) # 3:5 代表行索引, 1:3 代表列索引
Out [12]: b c
2019-05-04 13 14
2019-05-05 17 18
選擇 DataFrame 的一個(gè)不連續(xù)數(shù)據(jù)區(qū)域:
In [13]: print(df2.iloc[[1,3,5],1:3])
Out [13]: b c
2019-05-02 5 6
2019-05-04 13 14
2019-05-06 21 22
根據(jù)判斷條件篩選 DataFrame 中數(shù)據(jù)區(qū)域:
In [14]: print(df2[df2.a<9])
Out [14]: a b c d
2019-05-01 0 1 2 3
2019-05-02 4 5 6 7
2019-05-03 8 9 10 11
DataFrame 處理缺失值,丟棄存在缺失值的行:
In [15]: df = pd.DataFrame(np.arange(24).reshape(6,4),index=dates,columns=['A','B','C','D'])
df.iloc[0,1]=np.nan
df.iloc[1,1] = np.nan
print(df)
#丟掉空值所在行或者列 how='any' 或者 'all'
df1 = df.dropna(axis=0,how='any')
print(df1)
Out [15]: A B C D
2019-05-01 0 NaN 2 3
2019-05-02 4 NaN 6 7
2019-05-03 8 9.0 10 11
2019-05-04 12 13.0 14 15
2019-05-05 16 17.0 18 19
2019-05-06 20 21.0 22 23
A B C D
2019-05-03 8 9.0 10 11
2019-05-04 12 13.0 14 15
2019-05-05 16 17.0 18 19
2019-05-06 20 21.0 22 23
DataFrame 處理缺失值油够,丟棄存在缺失值的列:
In [16]: df1 = df.dropna(axis=1,how='any')
print(df1)
Out [16]: A C D
2019-05-01 0 2 3
2019-05-02 4 6 7
2019-05-03 8 10 11
2019-05-04 12 14 15
2019-05-05 16 18 19
2019-05-06 20 22 23
填充缺失值為指定的值:
In [17]: df2 = df.fillna(value=1)
print(df2)
Out [17]: A B C D
2019-05-01 0 1.0 2 3
2019-05-02 4 1.0 6 7
2019-05-03 8 9.0 10 11
2019-05-04 12 13.0 14 15
2019-05-05 16 17.0 18 19
2019-05-06 20 21.0 22 23
判斷一個(gè) DataFrame 中是否有缺失值:
In [18]: print(np.any(df2.isnull())==True) # 用numpy判斷df.isnull()是否有True
Out [18]: False
用 pandas 讀一個(gè) csv 格式的文件為 DataFrame:
In [19]: import pandas as pd
data = pd.read_csv("D:\\geno1_1.csv")
Out [19]:
合并多個(gè)相同結(jié)構(gòu)的 DataFrame:
In [20]: df1 = pd.DataFrame(np.ones((3,4))*0,columns=['A','B','C','D'])
df2 = pd.DataFrame(np.ones((3,4))*1,columns=['A','B','C','D'])
df3 = pd.DataFrame(np.ones((3,4))*2,columns=['A','B','C','D'])
df4 = pd.concat([df1,df2,df3],axis=0,ignore_index=True) # 合并df1蚁袭,df2,df3石咬,axis=0代表是對(duì)行操作揩悄。ignore_index=True是代表忽略原先的行索引
print(df4)
Out [20]: A B C D
0 0.0 0.0 0.0 0.0
1 0.0 0.0 0.0 0.0
2 0.0 0.0 0.0 0.0
3 1.0 1.0 1.0 1.0
4 1.0 1.0 1.0 1.0
5 1.0 1.0 1.0 1.0
6 2.0 2.0 2.0 2.0
7 2.0 2.0 2.0 2.0
8 2.0 2.0 2.0 2.0
對(duì)不同結(jié)構(gòu)的 DataFrame 進(jìn)行合并操作:
In [21]: df1 = pd.DataFrame(np.ones((3,4))*0,columns=['A','B','C','D'],index=[1,2,3])
df2 = pd.DataFrame(np.ones((3,4))*1,columns=['B','C','D','E'],index=[2,3,4])
df3 = pd.concat([df1,df2],axis=0,ignore_index=True)
print(df3)
Out [21]: A B C D E
0 0.0 0.0 0.0 0.0 NaN
1 0.0 0.0 0.0 0.0 NaN
2 0.0 0.0 0.0 0.0 NaN
3 NaN 1.0 1.0 1.0 1.0
4 NaN 1.0 1.0 1.0 1.0
5 NaN 1.0 1.0 1.0 1.0
合并操作只保留相同的部分:
In [22]: df3 = pd.concat([df1,df2],join='inner',axis=0,ignore_index=True)
print(df3)
Out [22]: B C D
0 0.0 0.0 0.0
1 0.0 0.0 0.0
2 0.0 0.0 0.0
3 1.0 1.0 1.0
4 1.0 1.0 1.0
5 1.0 1.0 1.0
用 merge
的方式進(jìn)行合并,根據(jù)一個(gè) key
:
In [23]: import pandas as pd
left = pd.DataFrame({'key':['K0','K1','K2','K3'],
'A':['A0','A1','A2','A3'],
'B':['B0','B1','B2','B3']})
right = pd.DataFrame({'key':['K0','K1','K2','K3'],
'C':['C0','C1','C2','C3'],
'D':['D0','D1','D2','D3']})
print(left)
print(right)
Out [23]: key A B
0 K0 A0 B0
1 K1 A1 B1
2 K2 A2 B2
3 K3 A3 B3
key C D
0 K0 C0 D0
1 K1 C1 D1
2 K2 C2 D2
3 K3 C3 D3
合并的方式有四種 how = 'inner' 'outer' 'left' 'right'
鬼悠,默認(rèn)為 'inner'
合并:
In [24]: res = pd.merge(left,right,on='key')
print(res)
Out [24]: key A B C D
0 K0 A0 B0 C0 D0
1 K1 A1 B1 C1 D1
2 K2 A2 B2 C2 D2
3 K3 A3 B3 C3 D3