python3 科學計算之pandas入門(二)


 

一.基本功能

對於時間序列這樣的有序數據,重新索引時可能需要做一些插值處理。method選項即可達到此目的,例如,使用ffill可以實現前向值填充:

In [14]: obj3=Series(['red','yellow','blue'],index=[0,2,4])

In [15]: obj3
Out[15]:
0 red
2 yellow
4 blue
dtype: object

In [16]: obj3.reindex(range(6),method='ffill')
Out[16]:
0 red
1 red
2 yellow
3 yellow
4 blue
5 blue
dtype: object

下表列出了可用的method選項,其實我們有時需要比前向和后向填充更為精准的插值方式。

參數                                                     說明

ffill或pad                                     前向填充(或搬運)值

bfill或backfill                                后向填充(或搬運)值

 

對於DataFrame,reindex可以修改(行)索引、列、或兩個都修改。如果僅傳入一個序列,則會重新索引行:

In [19]: frame=DataFrame(np.arange(9).reshape((3,3)),index=['a','b','c'],column
...: s=['Calvin','Kobe','Michale'])

In [20]: frame
Out[20]:
  Calvin Kobe Michale
a   0       1            2
b   3       4            5
c 6 7 8

In [21]: frame2=frame.reindex(['b','c','d','e'])

In [22]: frame2
Out[22]:
   Calvin Kobe Michale
b  3.0   4.0      5.0
c  6.0    7.0      8.0
d NaN NaN NaN
e NaN NaN NaN

使用columns關鍵字即可重新索引列:

In [23]: name=['Calvin','Kobe','KD']

In [24]: frame.reindex(columns=name)
Out[24]:
  Calvin Kobe KD
a  0       1      NaN
b  3       4      NaN
c  6       7      NaN

也可以同時對行和列進行重新索引,而插值則只能按行應用(即軸0):

In [26]: frame.reindex(index=['a','b','c','d'],method='ffill',columns=name)
Out[26]:
   Calvin Kobe KD
a    0       1       0
b    3       4       3
c    6       7       6
d    6       7       6

 

下表列出了reindex函數的各參數及說明

參數                            說明

index           用作索引的新序列。既可以是Index實例,也可以是其他序列型的Python數據結構,index會被完全使用,就像沒有任何復制一樣

method        插值(填充)方式,具體參數見上表

fill_value      在重新索引的過程中,需要引入缺失值時使用的替代值

limit              前向或后向填充時的最大值充量

level             在MultiIndex的指定級別上匹配簡單索引,否則選取其子集

copy             默認為True,無論如何復制;如果為False,則新舊相等就不復制

 

丟棄指定軸上的項

丟棄某條軸上的一個或多個項很簡單,只要有一個索引數組或列表即可。由於需要執行一些數據整理和集合邏輯,所以drop方法返回的是一個指定軸上刪除了指定值的新對象

In [30]: obj=Series(np.arange(5),index=['a','b','c','d','e'])

In [31]: obj
Out[31]:
a 0
b 1
c 2
d 3
e 4
dtype: int32

In [32]: new_obj=obj.drop('c')

In [33]: new_obj
Out[33]:
a 0
b 1
d 3
e 4
dtype: int32

In [34]: new_obj=obj.drop(['c','d'])

In [35]: new_obj
Out[35]:
a 0
b 1
e 4
dtype: int32

 

對於DataFrame,可以刪除任意軸上的索引值:

In [6]: data=DataFrame(np.arange(16).reshape((4,4)),index=['CA','FL','HW','NY']
...: ,columns=['one','two','three','four'])

In [7]: data
Out[7]:
      one two three four
CA   0     1      2     3
FL    4     5      6     7
HW  8     9     10   11
NY  12    13   14   15

#刪除索引值為CA,FL的行

In [9]: data.drop(['CA','FL'])
Out[9]:
       one two three four
HW   8     9    10    11
NY   12   13   14   15

In [10]: data
Out[10]:
       one two three four
CA   0      1     2      3
FL    4      5     6      7
HW  8      9    10    11
NY 12     13   14    15

#刪除指定列(要加上軸)

In [12]: data.drop(['one','three'],axis=1)
Out[12]:
      two   four
CA   1      3
FL    5      7
HW  9     11
NY  13    15

 

索引、選取和過濾

Series索引的工作方式類似於Numpy數組的索引,只不過Series的索引值不只是整數

In [13]: obj=Series(np.arange(4),index=['a','b','c','d'])

In [14]: obj
Out[14]:
a 0
b 1
c 2
d 3
dtype: int32

In [15]: obj['c']
Out[15]: 2

In [16]: obj[0]
Out[16]: 0

#字母標簽包含末端

In [17]: obj['a':'c']
Out[17]:
a 0
b 1
c 2
dtype: int32 

#數字標簽跟python切片運算一樣,不包含末端

In [18]: obj[0:2]
Out[18]:
a 0
b 1
dtype: int32

In [19]: obj[0:3]
Out[19]:
a 0
b 1
c 2
dtype: int32

In [20]: obj[[1,3]]
Out[20]:
b 1
d 3
dtype: int32

對DataFrame進行索引其實就是獲取一個或多個列

In [26]: data=DataFrame(np.arange(16).reshape((4,4)),index=['CA','FL','HW','NY']
...: ,columns=['one','two','three','four'])

In [27]: data
Out[27]:
      one two three four
CA   0     1     2      3
FL    4     5     6      7
HW  8     9    10    11
NY  12   13    14   15

 

In [28]: data['one']
Out[28]:
CA 0
FL 4
HW 8
NY 12
Name: one, dtype: int32

In [30]: data[['three','one']]
Out[30]:
      three one
CA   2      0
FL    6      4
HW 10     8
NY  14     12

#通過切片或布爾型數組選取行:

In [31]: data[:2]
Out[31]:
      one two three four
CA    0    1    2       3
FL     4    5    6       7

In [32]: data[0:2]
Out[32]:
      one two three four
CA   0     1     2       3
FL    4     5     6       7

In [33]: data[data['two']>4]
Out[33]:
      one two three four
FL    4     5     6      7
HW  8     9    10    11
NY  12   13    14   15

#另一種用法是通過布爾型DataFrame進行索引

In [35]: data<5
Out[35]:
        one two three four
CA True True True True
FL True False False False
HW False False False False
NY False False False False

In [36]: data[data<5]=0

In [37]: data
Out[37]:
     one two three four
CA   0    0     0      0
FL    0    5     6      7
HW  8    9    10    11
NY  12  13    14   15

 

為了在DataFrame的行上進行標簽索引,我們引入專門的索引字段loc,iloc。它使你可以通過Numpy式的標記法以及軸標簽從DataFrame中選取行和列的子集,之前提到過這也是一種重新索引的簡單手段:

loc-----通過行標簽索引行數據

iloc-----通過行號索引行數據

In [56]: data.loc[['FL','NY'],['one','two']]   #通過loc索引行為'FL','NY',列為'one','two'的數據
Out[56]:
    one two
FL   0    5
NY 12  13

#通過iloc索引第一行數據

In [58]: data.iloc[:1]
Out[58]:
     one two three four
CA  0     0      0    0

 

#算術運算和數據對齊

pandas最重要的一個功能是,它可以對不同索引的對象進行算術運算。在將對象相加時,如果存在不同的索引對,則結果的索引就是該索引對的並集。

 

In [1]: import numpy as np

In [2]: from pandas import Series,DataFrame

In [3]: s1=Series([1.2,-2.8,3.4,1.5],index=['a','c','d','e'])

In [4]: s2=Series([3.1,4.3,-5,6,4.8],index=['a','c','e','f','g'])

In [5]: s1
Out[5]:
a 1.2
c -2.8
d 3.4
e 1.5
dtype: float64

In [6]: s2
Out[6]:
a 3.1
c 4.3
e -5.0
f 6.0
g 4.8
dtype: float64

 

將它們相加就會產生:

In [7]: s1+s2
Out[7]:
a 4.3
c 1.5
d NaN
e -3.5
f NaN
g NaN

dtype: float64

自動的數據對齊操作在不重疊的索引出引入了NA值。缺失值會在算術運算過程中傳播。

對於DataFrame,對齊操作會同時發生在行和列上:

In [8]: df1=DataFrame(np.arange(9).reshape((3,3)),columns=list('bcd'),index=['C
...: A','FL','NY'])

In [9]: df2=DataFrame(np.arange(12).reshape((4,3)),columns=list('bde'),index=['
...: UT','CA','NY','TE'])

In [10]: df1
Out[10]:
      b c d
CA 0 1 2
FL 3 4 5
NY 6 7 8

In [11]: df2
Out[11]:
      b d e
UT 0 1 2
CA 3 4 5
NY 6 7 8
TE 9 10 11

把它們相加后將會返回一個新的DataFrame,其索引和列為原來那兩個DataFrame的並集:

In [12]: df1+df2
Out[12]:
       b     c     d     e
CA 3.0 NaN 6.0 NaN
FL NaN NaN NaN NaN
NY 12.0 NaN 15.0 NaN
TE NaN NaN NaN NaN
UT NaN NaN NaN NaN

#在算術方法中填充值

在對不同索引的對象進行算術運算時,我們可能希望當一個對象中某軸標簽在另一個對相中找不到時填充一個特殊值(比如0):

In [14]: df1=DataFrame(np.arange(12).reshape((3,4)),columns=list('abcd'))

In [16]: df2=DataFrame(np.arange(20).reshape((4,5)),columns=list('abcde'))

In [17]: df1
Out[17]:
   a b c d
0 0 1 2 3
1 4 5 6 7
2 8 9 10 11

In [19]: df2
Out[19]:
   a b c d e
0 0 1 2 3 4
1 5 6 7 8 9
2 10 11 12 13 14
3 15 16 17 18 19

將它們相加時,沒有重疊的位置就會產生NA值:

In [20]: df1+df2
Out[20]:
    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 NaN

使用df1的add方法,傳入df2以及一個fill_value參數:

In [21]: df1.add(df2,fill_value=0)
Out[21]:
     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重新索引時,也可以指定一個填充值:

In [22]: df1.reindex(columns=df2.columns,fill_value=0)
Out[22]:
   a b c d e
0 0 1 2 3 0
1 4 5 6 7 0
2 8 9 10 11 0

下表列出了常用的算術方法

方法                           說明

add                        用於加法(+)的方法

sub                         用於減法(-)的方法

div                          用於除法(/)的方法

mul                         用於乘法(*)的方法

 

#DataFrame和Series之間的運算

 跟Numpy數組一樣,DataFrame和Series之間算術運算也是有明確規定的,看下例計算一個二維數組與其某行之間的差:

In [25]: arr=np.arange(12).reshape((3,4))

In [26]: arr
Out[26]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])

In [27]: arr[0]
Out[27]: array([0, 1, 2, 3])

In [28]: arr-arr[0]
Out[28]:
array([[0, 0, 0, 0],
[4, 4, 4, 4],
[8, 8, 8, 8]])

這就叫做廣播。DataFrame和Series之間的運算差不多也是如此:

In [29]: frame=DataFrame(np.arange(12).reshape((4,3)),columns=list('bde'),index
...: =['UT','CA','TE','NY'])

In [30]: series=frame.iloc[0]

In [31]: frame
Out[31]:
      b d e
UT 0 1 2
CA 3 4 5
TE 6 7 8
NY 9 10 11

In [32]: series
Out[32]:
b 0
d 1
e 2
Name: UT, dtype: int32

默認情況下,DataFrame和Series之間的算術運算會將Series的索引匹配到DataFrame的列,然后沿着行一直向下廣播:

In [36]: frame-series
Out[36]:
      b d e
UT 0 0 0
CA 3 3 3
TE 6 6 6
NY 9 9 9

如果某個索引值在DataFrame的列或Series的索引中找不到,則參與運算的兩個對象就會被重新索引以形成並集:

In [37]: series2=Series(range(3),index=['b','e','f'])

In [38]: series2
Out[38]:
b 0
e 1
f 2
dtype: int64

In [39]: frame+series2
Out[39]:
        b    d      e     f
UT 0.0 NaN 3.0 NaN
CA 3.0 NaN 6.0 NaN
TE 6.0 NaN 9.0 NaN
NY 9.0 NaN 12.0 NaN

如果希望匹配行且在列上廣播,則必須使用算術運算方法。例如:

In [43]: series3=frame['d']

In [44]: series3
Out[44]:
UT 1
CA 4
TE 7
NY 10
Name: d, dtype: int32

In [45]: frame
Out[45]:
      b d e
UT 0 1 2
CA 3 4 5
TE 6 7 8
NY 9 10 11

In [46]: frame.sub(series3,axis=0)
Out[46]:
       b d e
UT -1 0 1
CA -1 0 1
TE -1 0 1
NY -1 0 1

傳入的軸號就是希望匹配的軸。在本例中,我們的目的是匹配DataFrame的行索引並進行廣播。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM