1. 程式人生 > >Python資料分析入門之pandas總結基礎

Python資料分析入門之pandas總結基礎

一. Series

Series: pandas的長槍(資料表中的一列或一行,觀測向量,一維陣列...)


Series1 = pd.Series(np.random.randn(4))

print Series1,type(Series1) 

print Series1.index

print Series1.values

輸出結果:


0   -0.676256

1    0.533014

2   -0.935212

3   -0.940822

dtype: float64 <class 'pandas.core.series.Series'>

Int64Index([0
, 1, 2, 3], dtype='int64') [-0.67625578 0.53301431 -0.93521212 -0.94082195]

Series⽀持過濾的原理就如同NumPy


print Series1>0 

print Series1[Series1>0]

輸出結果如下:


0 0.030480

1 0.072746

2 -0.186607

3 -1.412244

dtype: float64 <class 'pandas.core.series.Series'>

Int64Index([0, 1
, 2, 3], dtype='int64') [ 0.03048042 0.07274621 -0.18660749 -1.41224432]

我發現,邏輯表示式,獲得的值就是True或者False。要先取得值,還是要X[y]的形式。

當然也支援廣播Broadcasting

什麼是broadcasting,暫時我也不太清楚,看個栗子:


print Series1*2 

print Series1+5

輸出結果如下:

0 0.06096

1 1 0.145492 

2 -0.373215 

3 -2.824489 

dtype: float64 

0 5.030480 

1 5.072746 

2 4.813393
3 3.587756 dtype: float64

以及Universal Function

numpy.frompyfunc(out,nin,nout) 返回的是一個函式,nin是輸入的引數個數,nout是函式返回的物件的個數函式說明

在序列上就使用行標,而不是建立1個2列的資料表,能夠輕鬆辨別哪是資料,哪是元資料

這句話的意思,我的理解是序列儘量是一列,不用去建立2列,這樣子,使用index就能指定資料了`


Series2 = pd.Series(Series1.values,index=['norm_'+unicode(i) for i in xrange(4)])

print Series2,type(Series2)

print Series2.index

print type(Series2.index)

print Series2.values

輸出結果如下,可以看到,它是通過修改了index值的樣式,並沒有建立2列。


norm_0   -0.676256

norm_1    0.533014

norm_2   -0.935212

norm_3   -0.940822

dtype: float64 <class 'pandas.core.series.Series'>

Index([u'norm_0', u'norm_1', u'norm_2', u'norm_3'], dtype='object')

<class 'pandas.core.index.Index'>

[-0.67625578  0.53301431 -0.93521212 -0.94082195]

雖然行是有順序的,但是仍然能夠通過行級的index來訪問到資料:

(當然也不盡然像Ordered Dict,因為⾏索引甚⾄可以重複,不推薦重複的行索引不代表不能用)


print Series2[['norm_0','norm_3']]

可以看到,讀取資料時,確實要採用X[y]的格式。這裡X[[y]]是因為,它要讀取兩個資料,指定的是這兩個資料的index值,將index值存放進list中,然後讀取。輸出結果如下:


norm_0   -0.676256

norm_3   -0.940822

dtype: float64

再比如:


print 'norm_0' in Series2

print 'norm_6' in Series2

輸出結果:


True

False

邏輯表示式的輸出結果,布林型值。

從Key不重複的Ordered Dict或者從Dict來定義Series就不需要擔心行索引重複:


Series3_Dict = {"Japan":"Tokyo","S.Korea":"Seoul","China":"Beijing"}

Series3_pdSeries = pd.Series(Series3_Dict)

print Series3_pdSeries

print Series3_pdSeries.values

print Series3_pdSeries.index

輸出結果:


China Beijing

Japan Tokyo

S.Korea Seoul

dtype: object

['Beijing' 'Tokyo' 'Seoul']

Index([u'China', u'Japan', u'S.Korea'], dtype='object')

通過上面的輸出結果就知道了,輸出結果是無序的,和輸入順序無關。

想讓序列按你的排序⽅式儲存?就算有缺失值都毫無問題


Series4_IndexList = ["Japan","China","Singapore","S.Korea"]

Series4_pdSeries = pd.Series( Series3_Dict ,index = Series4_IndexList)

print Series4_pdSeries

print Series4_pdSeries.values

print Series4_pdSeries.index

print Series4_pdSeries.isnull()

print Series4_pdSeries.notnull()

上面這樣的輸出就會按照list中定義的順序輸出結果。

整個序列級別的元資料資訊:name

當資料序列以及index本身有了名字,就可以更方便的進行後續的資料關聯啦!

這裡我感覺就是列名的作用。下面舉例:


print Series4_pdSeries.name

print Series4_pdSeries.index.name

很顯然,輸出的結果都是None,因為我們還沒指定name嘛!


Series4_pdSeries.name = "Capital Series"

Series4_pdSeries.index.name = "Nation"

print Series4_pdSeries

輸出結果:


Nation

Japan Tokyo

China Beijing

Singapore NaN

S.Korea Seoul

Name: Capital Series, dtype: object

"字典"?不是的,⾏index可以重複,儘管不推薦。


Series5_IndexList = ['A','B','B','C']

Series5 = pd.Series(Series1.values,index = Series5_IndexList)

print Series5

print Series5[['B','A']]

輸出結果:


A 0.030480

B 0.072746

B -0.186607

C -1.412244

dtype: float64

B 0.072746

B -0.186607

A 0.030480

dtype: float64

我們可以看出,Series['B']輸出了兩個值,所以index值儘量不要重複呀!

二. DataFrame

DataFrame:pandas的戰錘(資料表,⼆維陣列)

Series的有序集合,就像R的DataFrame一樣方便。

仔細想想,絕大部分的資料形式都可以表現為DataFrame。

從NumPy二維陣列、從檔案或者從資料庫定義:資料雖好,勿忘列名


dataNumPy = np.asarray([('Japan','Tokyo',4000),('S.Korea','Seoul',1300),('China','Beijing',9100)])

DF1 = pd.DataFrame(dataNumPy,columns=['nation','capital','GDP'])

DF1

這裡DataFrame中的columns應該就是列名的意思。現在看print的結果,是不是很舒服啊!Excel的樣式嘛

等長的列資料儲存在一個字典裡(JSON):很不幸,字典key是無序的


dataDict = {'nation':['Japan','S.Korea','China'],'capital':['Tokyo','Seoul','Beijing'],'GDP':[4900,1300,9100]}

DF2 = pd.DataFrame(dataDict)

DF2

輸出結果可以發現,無序的!

GDP    capital    nation

0 4900 Tokyo Japan

1 1300 Seoul S.Korea

2 9100 Beijing China

PS:由於懶得截圖放過來,這裡沒有了邊框線。

從另一個DataFrame定義DataFrame:啊,強迫症犯了!


DF21 = pd.DataFrame(DF2,columns=['nation','capital','GDP'])

DF21

很明顯,這裡是利用DF2定義DF21,還通過指定cloumns改變了列名的順序。


DF22 = pd.DataFrame(DF2,columns=['nation','capital','GDP'],index = [2,0,1])

DF22

很明顯,這裡定義了columns的順序,還定義了index的順序。


nation capital GDP

2 China Beijing 9100

0 Japan Tokyo 4900

1 S.Korea Seoul 1300

從DataFrame中取出列?兩種方法(與JavaScript完全一致!)

OMG,囧,我竟然都快忘了js語法了,現在想起了,但是物件的屬性既可以obj.x也可以obj[x]

  • '.'的寫法容易與其他預留關鍵字產生衝突

  • '[ ]'的寫法最安全。

從DataFrame中取出行?(至少)兩種⽅法:

  • 方法1和方法2:


print DF22[0:1] #給出的實際是DataFrame

print DF22.ix[0] #通過對應Index給出⾏,**ix**好爽。

輸出結果:


 nation  capital   GDP

2  China  Beijing  9100

nation     Japan

capital    Tokyo

GDP         4900

Name: 0, dtype: object
  • 方法3 像NumPy切片一樣的終極招式:iloc 


print DF22.iloc[0,:]    #第一個引數是第幾行,第二個引數是列。這裡呢,就是第0行,全部列

print DF22.iloc[:,0]    #根據上面的描述,這裡是全部行,第0列

輸出結果,驗證一下:


nation       China

capital    Beijing

GDP           9100

Name: 2, dtype: object

2      China

0      Japan

1    S.Korea

Name: nation, dtype: object

動態增加列列,但是無法用"."的方式,只能用"[]"

舉個栗子說明一下就明白了:


DF22['population'] = [1600,130,55]

DF22

輸出結果:


nation    capital    GDP    population

2    China    Beijing    9100    1600

0    Japan    Tokyo    4900    130

1    S.Korea    Seoul    1300    55

三. Index:行級索引

Index:pandas進⾏資料操縱的鬼牌(行級索引)

⾏級索引是:

  • 元資料

  • 可能由真實資料產生,因此可以視作資料

  • 可以由多重索引也就是多個列組合而成

  • 可以和列名進行交換,也可以進行堆疊和展開,達到Excel透視表效果

Index有四種...哦不,很多種寫法,⼀些重要的索引型別包括:

  • pd.Index(普通)

  • Int64Index(數值型索引)

  • MultiIndex(多重索引,在資料操縱中更詳細描述)

  • DatetimeIndex(以時間格式作為索引)

  • PeriodIndex (含週期的時間格式作為索引)

直接定義普通索引,長得就和普通的Series⼀樣


index_names = ['a','b','c']

Series_for_Index = pd.Series(index_names)

print pd.Index(index_names)

print pd.Index(Series_for_Index)

輸出結果:


Index([u'a', u'b', u'c'], dtype='object')

Index([u'a', u'b', u'c'], dtype='object')

可惜Immutable,牢記! 不可變!舉例如下:此處挖坑啊。不明白……


index_names = ['a','b','c'] 

index0 = pd.Index(index_names) 

print index0.get_values() 

index0[2] = 'd'

輸出結果如下:


['a' 'b' 'c']

---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

<ipython-input-36-f34da0a8623c> in <module>()

      2 index0 = pd.Index(index_names)

      3 print index0.get_values()

----> 4 index0[2] = 'd'



C:\Anaconda\lib\site-packages\pandas\core\index.pyc in __setitem__(self, key, value)

   1055 

   1056     def __setitem__(self, key, value):

-> 1057         raise TypeError("Indexes does not support mutable operations")

   1058 

   1059     def __getitem__(self, key):



TypeError: Indexes does not support mutable operations

扔進去一個含有多元組的List,就有了MultiIndex

可惜,如果這個List Comprehension改成小括號,就不對了。


multi1 = pd.Index([('Row_'+str(x+1),'Col_'+str(y+1)) for x in xrange(4) for y in xrange(4)])

multi1.name = ['index1','index2']

print multi1

輸出結果:


MultiIndex(levels=[[u'Row_1', u'Row_2', u'Row_3', u'Row_4'], [u'Col_1', u'Col_2', u'Col_3', u'Col_4']],

           labels=[[0,