DataFrame是一種表格型數據結構,它含有一組有序的列,每列可以是不同的值。DataFrame既有行索引,也有列索引,它可以看作是由Series組成的字典,不過這些Series公用一個索引。
DataFrame的創建有多種方式,不過最重要的還是根據dict進行創建,以及讀取csv或者txt文件來創建。這裡主要介紹這兩種方式。
根據字典創建
data = { 'state':['Ohio','Ohio','Ohio','Nevada','Nevada'], 'year':[2000,2001,2002,2001,2002], 'pop':[1.5,1.7,3.6,2.4,2.9]}frame = pd.DataFrame(data)frame#輸出 pop state year0 1.5 Ohio 20001 1.7 Ohio 20012 3.6 Ohio 20023 2.4 Nevada 20014 2.9 Nevada 2002
DataFrame的行索引是index,列索引是columns,我們可以在創建DataFrame時指定索引的值:
frame2 = pd.DataFrame(data,index=['one','two','three','four','five'],columns=['year','state','pop','debt'])frame2#輸出 year state pop debtone 2000 Ohio 1.5 NaNtwo 2001 Ohio 1.7 NaNthree 2002 Ohio 3.6 NaNfour 2001 Nevada 2.4 NaNfive 2002 Nevada 2.9 NaN
使用嵌套字典也可以創建DataFrame,此時外層字典的鍵作為列,內層鍵則作為索引:
pop = {'Nevada':{2001:2.4,2002:2.9},'Ohio':{2000:1.5,2001:1.7,2002:3.6}}frame3 = pd.DataFrame(pop)frame3#輸出 Nevada Ohio2000 NaN 1.52001 2.4 1.72002 2.9 3.6
我們可以用index,columns,values來訪問DataFrame的行索引,列索引以及數據值,數據值返回的是一個二維的ndarray
frame2.values#輸出array([[2000, 'Ohio', 1.5, 0], [2001, 'Ohio', 1.7, 1], [2002, 'Ohio', 3.6, 2], [2001, 'Nevada', 2.4, 3], [2002, 'Nevada', 2.9, 4]], dtype=object)
讀取文件
讀取文件生成DataFrame最常用的是read_csv,read_table方法。該方法中幾個重要的參數如下所示:
其他創建DataFrame的方式有很多,比如我們可以通過讀取mysql或者mongoDB來生成,也可以讀取json文件等等,這裡就不再介紹。
2、DataFrame軸的概念在DataFrame的處理中經常會遇到軸的概念,這裡先給大家一個直觀的印象,我們所說的axis=0即表示沿著每一列或行標籤\索引值向下執行方法,axis=1即表示沿著每一行或者列標籤模向執行對應的方法。
索引、切片
我們可以根據列名來選取一列,返回一個Series:
frame2['year']#輸出one 2000two 2001three 2002four 2001five 2002Name: year, dtype: int64
我們還可以選取多列或者多行:
data = pd.DataFrame(np.arange(16).reshape((4,4)),index = ['Ohio','Colorado','Utah','New York'],columns=['one','two','three','four'])data[['two','three']]#輸出 two threeOhio 1 2Colorado 5 6Utah 9 10New York 13 14#取行data[:2]#輸出 one two three fourOhio 0 1 2 3Colorado 4 5 6 7
當然,在選取數據的時候,我們還可以根據邏輯條件來選取:
data[data['three']>5]#輸出 one two three fourColorado 4 5 6 7Utah 8 9 10 11New York 12 13 14 15
pandas提供了專門的用於索引DataFrame的方法,即使用ix方法進行索引,不過ix在最新的版本中已經被廢棄了,如果要是用標籤,最好使用loc方法,如果使用下標,最好使用iloc方法:
#data.ix['Colorado',['two','three']]data.loc['Colorado',['two','three']]#輸出two 5three 6Name: Colorado, dtype: int64data.iloc[0:3,2]#輸出Ohio 2Colorado 6Utah 10Name: three, dtype: int64
修改數據
可以使用一個標量修改DataFrame中的某一列,此時這個標量會廣播到DataFrame的每一行上:
data = { 'state':['Ohio','Ohio','Ohio','Nevada','Nevada'], 'year':[2000,2001,2002,2001,2002], 'pop':[1.5,1.7,3.6,2.4,2.9]}frame2 = pd.DataFrame(data,index=['one','two','three','four','five'],columns=['year','state','pop','debt'])frame2frame2['debt']=16.5frame2#輸出year state pop debtone 2000 Ohio 1.5 16.5two 2001 Ohio 1.7 16.5three 2002 Ohio 3.6 16.5four 2001 Nevada 2.4 16.5five 2002 Nevada 2.9 16.5
也可以使用一個列表來修改,不過要保證列表的長度與DataFrame長度相同:
frame2.debt = np.arange(5)frame2#輸出 year state pop debtone 2000 Ohio 1.5 0two 2001 Ohio 1.7 1three 2002 Ohio 3.6 2four 2001 Nevada 2.4 3five 2002 Nevada 2.9 4
可以使用一個Series,此時會根據索引進行精確匹配:
val = pd.Series([-1.2,-1.5,-1.7],index=['two','four','five'])frame2['debt'] = valframe2#輸出 year state pop debtone 2000 Ohio 1.5 NaNtwo 2001 Ohio 1.7 -1.2three 2002 Ohio 3.6 NaNfour 2001 Nevada 2.4 -1.5five 2002 Nevada 2.9 -1.7
重新索引
使用reindex方法對DataFrame進行重新索引。對DataFrame進行重新索引,可以重新索引行,列或者兩個都修改,如果只傳入一個參數,則會從新索引行:
frame = pd.DataFrame(np.arange(9).reshape((3,3)),index=[1,4,5],columns=['Ohio','Texas','California'])frame2 = frame.reindex([1,2,4,5])frame2#輸出 Ohio Texas California1 0.0 1.0 2.02 NaN NaN NaN4 3.0 4.0 5.05 6.0 7.0 8.0states = ['Texas','Utah','California']frame.reindex(columns=states)#輸出 Texas Utah California1 1 NaN 24 4 NaN 55 7 NaN 8
填充數據只能按行填充,此時只能對行進行重新索引:
frame = pd.DataFrame(np.arange(9).reshape((3,3)),index = ['a','c','d'],columns = ['Ohio','Texas','California'])frame.reindex(['a','b','c','d'],method = 'bfill')#frame.reindex(['a','b','c','d'],method = 'bfill',columns=states) 報錯
丟棄指定軸上的值
可以使用drop方法丟棄指定軸上的值,不會對原DataFrame產生影響
frame = pd.DataFrame(np.arange(9).reshape((3,3)),index = ['a','c','d'],columns = ['Ohio','Texas','California'])frame.drop('a') #輸出Ohio Texas Californiaa 0 1 2c 3 4 5d 6 7 8frame.drop(['Ohio'],axis=1)#輸出 Texas Californiaa 1 2c 4 5d 7 8
算術運算
DataFrame在進行算術運算時會進行補齊,在不重疊的部分補足NA:
df1 = pd.DataFrame(np.arange(9).reshape((3,3)),columns=list('bcd'),index=['Ohio','Texas','Colorado'])df2 = pd.DataFrame(np.arange(12).reshape((4,3)),columns = list('bde'),index=['Utah','Ohio','Texas','Oregon'])df1 + df2#輸出 b c d eColorado NaN NaN NaN NaNOhio 3.0 NaN 6.0 NaNOregon NaN NaN NaN NaNTexas 9.0 NaN 12.0 NaNUtah NaN NaN NaN NaN
可以使用fill_value方法填充NA數據,不過兩個df中都為NA的數據,該方法不會填充:
df1.add(df2,fill_value=0)#輸出 b c d eColorado 6.0 7.0 8.0 NaNOhio 3.0 1.0 6.0 5.0Oregon 9.0 NaN 10.0 11.0Texas 9.0 4.0 12.0 8.0Utah 0.0 NaN 1.0 2.0
函數應用和映射
numpy的元素級數組方法,也可以用於操作Pandas對象:
frame = pd.DataFrame(np.random.randn(3,3),columns=list('bcd'),index=['Ohio','Texas','Colorado'])np.abs(frame)#輸出 b c dOhio 0.367521 0.232387 0.649330Texas 3.115632 1.415106 2.093794Colorado 0.714983 1.420871 0.557722
另一個常見的操作是,將函數應用到由各列或行所形成的一維數組上。DataFrame的apply方法即可實現此功能。
f = lambda x:x.max() - x.min()frame.apply(f)#輸出b 3.830616c 2.835978d 2.743124dtype: float64frame.apply(f,axis=1)#輸出Ohio 1.016851Texas 4.530739Colorado 2.135855dtype: float64def f(x): return pd.Series([x.min(),x.max()],index=['min','max'])frame.apply(f)#輸出 b c dmin -0.714983 -1.415106 -0.649330max 3.115632 1.420871 2.093794
元素級的Python函數也是可以用的,使用applymap方法:
format = lambda x:'%.2f'%xframe.applymap(format)#輸出b c dOhio 0.37 -0.23 -0.65Texas 3.12 -1.42 2.09Colorado -0.71 1.42 -0.56
排序和排名
對於DataFrame,sort_index可以根據任意軸的索引進行排序,並指定升序降序
frame = pd.DataFrame(np.arange(8).reshape((2,4)),index=['three','one'],columns=['d','a','b','c'])frame.sort_index()#輸出 d a b cone 4 5 6 7three 0 1 2 3frame.sort_index(1,ascending=False)#輸出 d a b cone 4 5 6 7three 0 1 2 3
DataFrame也可以按照值進行排序:
#按照任意一列或多列進行排序frame.sort_values(by=['a','b'])#輸出 d a b cthree 0 1 2 3one 4 5 6 7
匯總和計算描述統計
DataFrame中的實現了sum、mean、max等方法,我們可以指定進行匯總統計的軸,同時,也可以使用describe函數查看基本所有的統計項:
df = pd.DataFrame([[1.4,np.nan],[7.1,-4.5],[np.nan,np.nan],[0.75,-1.3]],index=['a','b','c','d'],columns=['one','two'])df.sum(axis=1)#輸出one 9.25two -5.80dtype: float64#Na會被自動排除,可以使用skipna選項來禁用該功能df.mean(axis=1,skipna=False)#輸出a NaNb 1.300c NaNd -0.275dtype: float64#idxmax返回間接統計,是達到最大值的索引df.idxmax()#輸出one btwo ddtype: object#describe返回的是DataFrame的匯總統計#非數值型的與數值型的統計返回結果不同df.describe()#輸出one twocount 3.000000 2.000000mean 3.083333 -2.900000std 3.493685 2.262742min 0.750000 -4.50000025% 1.075000 -3.70000050% 1.400000 -2.90000075% 4.250000 -2.100000max 7.100000 -1.300000
DataFrame也實現了corr和cov方法來計算一個DataFrame的相關係數矩陣和協方差矩陣,同時DataFrame也可以與Series求解相關係數。
frame1 = pd.DataFrame(np.random.randn(3,3),index=list('abc'),columns=list('abc'))frame1.corr#輸出<bound method DataFrame.corr of a b ca 1.253773 0.429059 1.535575b -0.113987 -2.837396 -0.894469c -0.548208 0.834003 0.994863>frame1.cov()#輸出a b ca 0.884409 0.357304 0.579613b 0.357304 4.052147 2.442527c 0.579613 2.442527 1.627843#corrwith用於計算每一列與Series的相關係數frame1.corrwith(frame1['a'])#輸出a 1.000000b 0.188742c 0.483065dtype: float64
處理缺失數據
Pandas中缺失值相關的方法主要有以下三個:
isnull方法用於判斷數據是否為空數據;
fillna方法用於填補缺失數據;
dropna方法用於捨棄缺失數據。
上面兩個方法返回一個新的Series或者DataFrame,對原數據沒有影響,如果想在原數據上進行直接修改,使用inplace參數:
data = pd.DataFrame([[1,6.5,3],[1,np.nan,np.nan],[np.nan,np.nan,np.nan],[np.nan,6.5,3]])data.dropna()#輸出 0 1 20 1.0 6.5 3.0
對DataFrame來說,dropna方法如果發現缺失值,就會進行整行刪除,不過可以指定刪除的方式,how=all,是當整行全是na的時候才進行刪除,同時還可以指定刪除的軸。
data.dropna(how='all',axis=1,inplace=True)data#輸出0 1 20 1.0 6.5 3.01 1.0 NaN NaN2 NaN NaN NaN3 NaN 6.5 3.0
DataFrame填充缺失值可以統一填充,也可以按列填充,或者指定一種填充方式:
data.fillna({1:2,2:3})#輸出0 1 20 1.0 6.5 3.01 1.0 2.0 3.02 NaN 2.0 3.03 NaN 6.5 3.0data.fillna(method='ffill')#輸出0 1 20 1.0 6.5 3.01 1.0 6.5 3.02 1.0 6.5 3.03 1.0 6.5 3.0