1. 程式人生 > 其它 >pandas筆記

pandas筆記

Pandas類似R語言中的資料框(DataFrame),Pandas基於Numpy,但是對於資料框結構的處理比Numpy要來的容易。

1. Pandas的基本資料結構和使用

Pandas有兩個主要的資料結構:Series和DataFrame。Series類似Numpy中的一維陣列,DataFrame則是使用較多的多維表格資料結構。

Series的建立


>>>import numpy as np
>>>import pandas as pd
>>>s=pd.Series([1,2,3,np.nan,44,1]) # np.nan建立一個缺失數值
>>>s # 若未指定,Series會自動建立index,此處自動建立索引0-5
0 1.0
1 2.0
2 3.0
3 NaN
4 44.0
5 1.0
dtype: float64

DataFrame的建立


>>>dates=pd.date_range('20170101',periods=6)
>>>dates
DatetimeIndex(['2017-01-01', '2017-01-02', '2017-01-03', '2017-01-04',
'2017-01-05', '2017-01-06'],
dtype='datetime64[ns]', freq='D')
>>>df=pd.DataFrame(np.random.randn(6,4),index=dates,columns=['a','b','c','d'])
>>>df
a b c d
2017-01-01 -1.993447 1.272175 -1.578337 -1.972526
2017-01-02 0.092701 -0.503654 -0.540655 -0.126386
2017-01-03 0.191769 -0.578872 -1.693449 0.457891
2017-01-04 2.121120 0.521884 -0.419368 -1.916585
2017-01-05 1.642063 0.222134 0.108531 -1.858906
2017-01-06 0.636639 0.487491 0.617841 -1.597920

DataFrame可以跟Numpy一樣根據索引取出其中的資料,只是DataFrame索引方式更加多樣化。DataFrame不僅可以根據預設的行列編號來索引,還可以根據標籤序列來索引。

還可以採用字典的方式建立DataFrame:


>>>df2=pd.DataFrame({'a':1,'b':'hello kitty','c':np.arange(2),'d':['o','k']})
>>>df2
a b c d
0 1 hello kitty 0 o
1 1 hello kitty 1 k

對於DataFrame的一些屬性也可以採用相應的方法檢視


dtype # 檢視資料型別
index # 檢視行序列或者索引
columns # 檢視各列的標籤
values # 檢視資料框內的資料,也即不含表頭索引的資料
describe # 檢視資料的一些資訊,如每一列的極值,均值,中位數之類的,只能對數值型資料統計資訊
transpose # 轉置,也可用T來操作
sort_index # 排序,可按行或列index排序輸出
sort_values # 按資料值來排序

一些例子


>>>df2.dtypes
a int64
b object
c int64
d object
dtype: object
>>>df2.index
RangeIndex(start=0, stop=2, step=1)
>>>df2.columns
Index(['a', 'b', 'c', 'd'], dtype='object')
>>>df2.values
array([[1, 'hello kitty', 0, 'o'],
[1, 'hello kitty', 1, 'k']], dtype=object)
>>>df2.describe # 只能對數值型資料統計資訊
a c
count 2.0 2.000000
mean 1.0 0.500000
std 0.0 0.707107
min 1.0 0.000000
25% 1.0 0.250000
50% 1.0 0.500000
75% 1.0 0.750000
max 1.0 1.000000
>>>df2.T
0 1
a 1 1
b hello kitty hello kitty
c 0 1
d o k
>>>df2.sort_index(axis=1,ascending=False) # axis=1 按列標籤從大到小排列
d c b a
0 o 0 hello kitty 1
1 k 1 hello kitty 1
>>>df2.sort_index(axis=0,ascending=False) # 按行標籤從大到小排序
a b c d
1 1 hello kitty 1 k
0 1 hello kitty 0 o
>>>df2.sort_values(by="c",ascending=False) # 按c列的值從大到小排序
 a b c d
1 1 hello kitty 1 k
0 1 hello kitty 0 o

2. 從DataFrame中篩選取出目的資料

從DataFrame中取出目的資料方法有多種,一般常用的有:

    • 直接根據索引選取

    • 根據標籤選取(縱向選擇列):loc

    • 根據序列(橫向選擇行): iloc

    • 組合使用標籤序列來選取特定位置的資料: ix

    • 通過邏輯判斷篩選

簡單選取


>>>import numpy as np
>>>import pandas as pd
>>>dates=pd.date_range('20170101',periods=6)
>>>df=pd.DataFrame(np.arange(24).reshape((6,4)),index=dates,columns=['a','b','c','d'])
>>>df
a b c d
2017-01-01 0 1 2 3
2017-01-02 4 5 6 7
2017-01-03 8 9 10 11
2017-01-04 12 13 14 15
2017-01-05 16 17 18 19
2017-01-06 20 21 22 23
>>>df['a'] # 根據表籤直接選取a列,也可用df.a,結果相同
2017-01-01 0
2017-01-02 4
2017-01-03 8
2017-01-04 12
2017-01-05 16
2017-01-06 20
Freq: D, Name: a, dtype: int64
>>>df[0:3] # 選擇前3行,也可用行標籤 df['2017-01-01':'2017-01-03'],結果相同,但是無法用此法選擇多列
a b c d
2017-01-01 0 1 2 3
2017-01-02 4 5 6 7
2017-01-03 8 9 10 11

loc使用顯式的行標籤來選取資料

DataFrame行的表示方式有兩種,一種是通過顯式的行標籤來索引,另一種是通過預設隱式的行號來索引。loc方法是通過行標籤來索引選取目標行,可以配合列標籤來選取特定位置的資料。


>>>df.loc['2017-01-01':'2017-01-03']
a b c d
2017-01-01 0 1 2 3
2017-01-02 4 5 6 7
2017-01-03 8 9 10 11
>>>df.loc['2017-01-01',['a','b']] # 選取特定行的a,b列
a 0
b 1
Name: 2017-01-01 00:00:00, dtype: int64

iloc使用隱式的行序列號來選取資料

使用iloc可以搭配列序列號來更簡單的選取特定位點的資料


>>>df.iloc[3,1]
13
>>>df.iloc[1:3,2:4]
c d
2017-01-02 6 7
2017-01-03 10 11

ix利用ix可以混用顯式標籤與隱式序列號

loc只能使用顯式標籤來選取資料,而iloc只能使用隱式序列號來選取資料,ix則能將二者結合起來使用。


>>> df.ix[3:5,['a','b']]
a b
2017-01-04 12 13
2017-01-05 16 17

使用邏輯判斷來選取資料


>>>df
a b c d
2017-01-01 0 1 2 3
2017-01-02 4 5 6 7
2017-01-03 8 9 10 11
2017-01-04 12 13 14 15
2017-01-05 16 17 18 19
2017-01-06 20 21 22 23
>>>df[df['a']>5] # 等價於df[df.a>5]
a b c d
2017-01-03 8 9 10 11
2017-01-04 12 13 14 15
2017-01-05 16 17 18 19
2017-01-06 20 21 22 23

3. Pandas設定特定位置值


>>>import numpy as np
>>>import pandas as pd
>>>dates=pd.date_range('20170101',periods=6)
>>>datas=np.arange(24).reshape((6,4))
>>>columns=['a','b','c','d']
>>>df=pd.DataFra me(data=datas,index=dates,colums=columns)
>>>df.iloc[2,2:4]=111 # 將第2行2,3列位置的資料改為111
a b c d
2017-01-01 0 1 2 3
2017-01-02 4 5 6 7
2017-01-03 8 9 111 111
2017-01-04 12 13 14 15
2017-01-05 16 17 18 19
2017-01-06 20 21 22 23
>>>df.b[df['a']>10]=0 # 等價於df.b[df.a>10] # 以a列大於10的數的位置為參考,改變b列相應行的數值為0
a b c d
2017-01-01 0 1 2 3
2017-01-02 4 5 6 7
2017-01-03 8 9 111 111
2017-01-04 12 0 14 15
2017-01-05 16 0 18 19
2017-01-06 20 0 22 23
>>>df['f']=np.nan # 新建f列並設定數值為np.nan
a b c d f
2017-01-01 0 1 2 3 NaN
2017-01-02 4 5 6 7 NaN
2017-01-03 8 9 111 111 NaN
2017-01-04 12 0 14 15 NaN
2017-01-05 16 0 18 19 NaN
2017-01-06 20 0 22 23 NaN
>>>
# 用上面的方法也可以加上`Series`序列,但是必須與列長度一致
>>>df['e']=pd.Series(np.arange(6),index=dates)
>>>df
a b c d f e
2017-01-01 0 1 2 3 NaN 0
2017-01-02 4 5 6 7 NaN 1
2017-01-03 8 9 111 111 NaN 2
2017-01-04 12 0 14 15 NaN 3
2017-01-05 16 0 18 19 NaN 4
2017-01-06 20 0 22 23 NaN 5

4. 處理丟失資料

有時候我們的資料中會有一些空的或者缺失(NaN)資料,使用dropna可以選擇性的刪除或填補這些NaN資料。drop函式可以選擇性的刪除行或者列,drop_duplicates去除冗餘。fillna則將NaN值用其他值替換。操作後不改變原值,若要儲存更改需重新賦值。


>>>import numpy as np
>>>import pandas as pd
>>>df=pd.DataFrame(np.arange(24).reshape(6,4),index=pd.date_range('20170101',periods=6),columns=['a','b','c','d'])
>>>df
a b c d
2017-01-01 0 1 2 3
2017-01-02 4 5 6 7
2017-01-03 8 9 10 11
2017-01-04 12 13 14 15
2017-01-05 16 17 18 19
2017-01-06 20 21 22 23
>>>df.iloc[1,3]=np.nan
>>>di.iloc[3,2]=np.nan
>>>df.
a b c d
2017-01-01 0 1 2.0 3.0
2017-01-02 4 5 6.0 NaN
2017-01-03 8 9 10.0 11.0
2017-01-04 12 13 NaN 15.0
2017-01-05 16 17 18.0 19.0
2017-01-06 20 21 22.0 23.0
>>>df.dropna(axis=0,how='any') # axis=0(1)表示將含有NaN的行(列)刪除。
# how='any'表示只要行(或列,視axis取值而定)含有NaN則將該行(列)刪除,
# how='all'表示當某行(列)全部為NaN時才刪除
a b c d
2017-01-01 0 1 2.0 3.0
2017-01-03 8 9 10.0 11.0
2017-01-05 16 17 18.0 19.0
2017-01-06 20 21 22.0 23.0
>>>df.fillna(value=55)
a b c d
2017-01-01 0 1 2.0 3.0
2017-01-02 4 5 6.0 55.0
2017-01-03 8 9 10.0 11.0
2017-01-04 12 13 55.0 15.0
2017-01-05 16 17 18.0 19.0
2017-01-06 20 21 22.0 23.0

還可以利用函式來檢查資料中是否有或者全部為NaN


>>>np.any(df.isnull())==True
True
>>>np.all(df.isnull())==True
False

5. 資料的匯入以及匯出

一般excel檔案以csv方式讀入,pd.read_csv(file),data儲存為filedata.to_csv(file)。

6. 資料新增合併

本節主要學習Pandas的一些簡單基本的資料新增合併方法:concat,append。

concat合併方式類似於Numpy的concatenate方法,可橫向或者豎向合併。


>>>import numpy as np
>>>import pandas as pd
>>> 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'])
>>>res=pd.concat([df1,df2,df3],axis=0)
# axis=0表示按行堆疊合並,axis=1表示按列左右合併
>>>res
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
0 1.0 1.0 1.0 1.0
1 1.0 1.0 1.0 1.0
2 1.0 1.0 1.0 1.0
0 2.0 2.0 2.0 2.0
1 2.0 2.0 2.0 2.0
2 2.0 2.0 2.0 2.0
>>>
# 使用ignore_index=True引數可以重置行標籤
>>>res=pd.concat([df1,df2,df3],axis=0,ignore_index=True)
>>>res
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

join引數提供了更多樣化的合併方式。join=outer為預設值,表示將幾個合併的資料都用上,具有相同列標籤的合二為一,上下合併,不同列標籤的獨自成列,原來沒有數值的位置以NaN填充;join=inner則只將具有相同列標籤的(行)列上下合併,其餘的列捨棄。簡言之,outer代表並集,inner代表交集**。


>>>import numpy as np
>>>import pandas as pd
>>>df1=pd.DataFrame(np.ones((3,4)),index=[1,2,3],columns=['a','b','c','d'])
>>>df2=pd.DataFrame(np.ones((3,4))*2,index=[1,2,3],columns=['b','c','d','e'])
>>>res=pd.concat([df1,df2],axis=0,join='outer')
>>>res
a b c d e
1 1.0 1.0 1.0 1.0 NaN
2 1.0 1.0 1.0 1.0 NaN
3 1.0 1.0 1.0 1.0 NaN
1 NaN 2.0 2.0 2.0 2.0
2 NaN 2.0 2.0 2.0 2.0
3 NaN 2.0 2.0 2.0 2.0
>>>res1=pd.concat([df1,df2],axis=1,join='outer')
# axis=1表示按列左右合併具有相同的行標籤的,其餘的各成一行,NaN補齊空缺
>>>res1
a b c d b c d e
1 1.0 1.0 1.0 1.0 2.0 2.0 2.0 2.0
2 1.0 1.0 1.0 1.0 2.0 2.0 2.0 2.0
3 1.0 1.0 1.0 1.0 2.0 2.0 2.0 2.0
>>>res2=pd.concat([df1,df2],axis=0,join='inner',ignore_index=True)
# 將具有相同列標籤的列上下合併
>>>res2
b c d
0 1.0 1.0 1.0
1 1.0 1.0 1.0
2 1.0 1.0 1.0
3 2.0 2.0 2.0
4 2.0 2.0 2.0
5 2.0 2.0 2.0

join_axes引數可以設定參考系,以設定的參考來合併,參考系中沒有的捨棄掉


>>>import numpy as np
>>>import pandas as pd
>>>df1=pd.DataFrame(np.ones((3,4)),index=[1,2,3],columns=['a','b','c','d'])
>>> df2=pd.DataFrame(np.ones((3,4))*2,index=[2,3,4],columns=['b','c','d','e'])
>>>res3=pd.concat([df1,df2],axis=0,join_axes=[df1.columns])
# 以df1的列標籤為參考上下合併擁有相同列標籤的列
>>>res3
a b c d
1 1.0 1.0 1.0 1.0
2 1.0 1.0 1.0 1.0
3 1.0 1.0 1.0 1.0
2 NaN 2.0 2.0 2.0
3 NaN 2.0 2.0 2.0
4 NaN 2.0 2.0 2.0
>>>res4=pd.concat([df1,df2],axis=1,join_axes=[df1.index])
# 以df1行標籤為參考,左右合併擁有相同行標籤的各列
a b c d b c d e
1 1.0 1.0 1.0 1.0 NaN NaN NaN NaN
2 1.0 1.0 1.0 1.0 2.0 2.0 2.0 2.0
3 1.0 1.0 1.0 1.0 2.0 2.0 2.0 2.0

append只有上下合併,沒有左右合併

    >>>df1=pd.DataFrame(np.ones((3,4)),index=[1,2,3],columns=['a','b','c','d'])
    >>> df2=pd.DataFrame(np.ones((3,4))*2,index=[2,3,4],columns=['b','c','d','e'])
    >>>res5=df1.append(df2,ignore_index=True)
    >>>res5
        a  b  c  d  e
    0 1.0 1.0 1.0 1.0 NaN
    1 1.0 1.0 1.0 1.0 NaN
    2 1.0 1.0 1.0 1.0 NaN
    3 NaN 2.0 2.0 2.0 2.0
    4 NaN 2.0 2.0 2.0 2.0
    5 NaN 2.0 2.0 2.0 2.0

7. Pandas高階合併:merge

merge合併與concat類似,只是merge可以通過一個或多個鍵將兩個資料集的行連線起來。

    merge(left, right, how='inner', on=None, left_on=None, right_on=None, left_index=False, right_index=False, 
    sort=False, suffixes=('_x', '_y'), copy=True, indicator=False)

引數說明:

  • left與right: 兩個不同的DataFrame

  • how: 指的是合併(連線)的方式有inner(內連線),left(左外連線),right(右外連線),outer(全外連線);預設為inner

  • on : 指的是用於連線的列索引名稱。必須存在右右兩個DataFrame物件中,如果沒有指定且其他引數也未指定則以兩個DataFrame的列名交集做為連線鍵

  • left_on: 左側DataFrame中用作連線鍵的列名;這個引數中左右列名不相同,但代表的含義相同時非常有用。

  • right_on: 右側DataFrame中用作 連線鍵的列名

  • left_index: 使用左側DataFrame中的行索引做為連線鍵

  • right_index: 使用右側DataFrame中的行索引做為連線鍵

  • sort: 預設為True,將合併的資料進行排序。在大多數情況下設定為False可以提高效能

  • suffixes: 字串值組成的元組,用於指定當左右DataFrame存在相同列名時在列名後面附加的字尾名稱,預設為('x','y')

  • copy: 預設為True,總是將資料複製到資料結構中;大多數情況下設定為False可以提高效能

  • indicator: 顯示合併資料中來源情況;如只來自己於左邊(left_only)、兩者(both)

    >>>import pandas as pd
    >>>df1=pd.DataFrame({'key':['k0','k1','k2','k3'],'A':['a0','a1','a2','a3'],'B':['b0','b1','b2','b3']})
    >>>df2=pd.DataFrame({'key':['k0','k1','k2','k3'],'C':['c0','c1','c2','c3'],'D':['d0','d1','d2','d3']})
    >>> res=pd.merge(df1,df2,on='key',indicator=True)
    >>>res
      A  B key  C  D _merge
    0 a0 b0 k0 c0 d0  both
    1 a1 b1 k1 c1 d1  both
    2 a2 b2 k2 c2 d2  both
    3 a3 b3 k3 c3 d3  both

依據行index合併與依據列key合併用法類似

    >>>res2=pd.merge(df1,df2,left_index=True,right_index=True,indicator=True)
    >>>res2
      A  B key_x  C  D key_y _merge
    0 a0 b0  k0 c0 d0  k0  both
    1 a1 b1  k1 c1 d1  k1  both
    2 a2 b2  k2 c2 d2  k2  both
    3 a3 b3  k3 c3 d3  k3  both

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援指令碼之家。