Pandas 講解
Python Data Analysis Library 或 pandas 是基於NumPy 的一種工具,該工具是為了解決數據分析任務而創建的。
Pandas 納入了大量庫和一些標准的數據模型,提供了高效地操作大型數據集所需的工具。
pandas提供了大量能使我們快速便捷地處理數據的函數和方法。你很快就會發現,它是使Python成為強大而高效的數據分析環境的重要因素之一。
Series:一維數組,與Numpy中的一維array類似。 二者與Python基本的數據結構List也很相近,其區別是:List中的元素可以是不同的數據類型, 而Array和Series中則只允許存儲相同的數據類型,這樣可以更有效的使用內存,提高運算效率。 Time- Series:以時間為索引的Series。 DataFrame:二維的表格型數據結構。很多功能與R中的data.frame類似。 可以將DataFrame理解為Series的容器。以下的內容主要以DataFrame為主。 Panel :三維的數組,可以理解為DataFrame的容器。
---------------------------------------------------
Series
Series 是一種類似於一維數組的對象, 它由一組數據(各種numpy數據類型)以及一組與之相關的數據標簽(索引)組成。
""" In [1]: from pandas import Series In [2]: from pandas import DataFrame In [3]: obj = Series([4, 7, -5, 3]) In [4]: obj Out[4]: 0 4 1 7 2 -5 3 3 dtype: int64 """
Series 索引,指定索引(也就是左邊的列)
通過 上面的例子, 我們知道Series的字符表現形式為索引在左邊, 值在右邊。沒有指定索引,
那么索引會自動從0開始的整數型索引
可以通過Series的values和index屬性獲取其數組表示形式和索引對象。
""" In [5]: obj.values Out[5]: array([ 4, 7, -5, 3]) In [6]: obj.index Out[6]: RangeIndex(start=0, stop=4, step=1) """
那么我們可以自定義索引
In [7]: obj2 = Series([4, 7, -5, 3], index=['d', 'b', 'a', 'c']) In [8]: obj2 Out[8]: d 4 b 7 a -5 c 3 dtype: int64 In [9]: obj2.index Out[9]: Index([u'd', u'b', u'a', u'c'], dtype='object')
索引賦值
In [11]: obj2['d'] = 9 In [12]: obj2 Out[12]: d 9 b 7 a -5 c 3 dtype: int64
索引取值
In [13]: obj2[["a", "b", "c"]] Out[13]: a -5 b 7 c 3 dtype: int64
索引值映射
In:'b' in obj2 Out:True In:'f' in obj2 Out:False
通過字典創建Series
""" In [14]: sdata = {"Ohio":3500, "Texas":71000, "Oregon":16000, "Utah":51000} In [15]: obj3 = Series(sdata) In [16]: obj3 Out[16]: Ohio 3500 Oregon 16000 Texas 71000 Utah 51000 dtype: int64 """
索引匹配值和判斷缺失
相對應Series也可以匹配對應的索引,如果找不到結果為NaN(非數字),pandas中用於表示缺失的數據
同時isnull和notnull函數用於檢測缺失數據。
In [17]: states = ['California', 'Ohio', 'Oregon', 'Texas'] In [18]: obj4 = Series(sdata, index=states) In [19]: obj4 Out[19]: California NaN Ohio 3500.0 Oregon 16000.0 Texas 71000.0 dtype: float64
In [22]: pd.isnull(obj4) Out[22]: California True Ohio False Oregon False Texas False dtype: bool ------------- In [23]: pd.notnull(obj4) Out[23]: California False Ohio True Oregon True Texas True dtype: bool ----------- In [24]: obj4.isnull() Out[24]: California True Ohio False Oregon False Texas False dtype: bool
Series 數據對齊
In [25]: obj3 + obj4 Out[25]: California NaN Ohio 7000.0 Oregon 32000.0 Texas 142000.0 Utah NaN dtype: float64
name屬性
Series 對象本身及其索引都有一個name屬性, 該屬性跟pandas其他的關鍵功能關系非常密切
In [26]: obj4.name = 'population' In [27]: obj4.index.name = 'state' In [29]: obj4 Out[29]: state California NaN Ohio 3500.0 Oregon 16000.0 Texas 71000.0 Name: population, dtype: float64
Series修改索引名稱
Series 的索引也可以通過索引的方式就地修改
In [30]: obj.index = ['Bob', 'Steve', 'Jeff', 'Ryan'] In [31]: obj Out[31]: Bob 4 Steve 7 Jeff -5 Ryan 3 dtype: int64
--------------------------------------------------------
DataFrame及常用方法
ix 標簽索引
T index和columns變換方向
index
reindex
DataFrame 是一個表格行的數據結構, 他含有一組有序的列,每列可以是不同的值類型
(數值,字符串,布爾值等)。
DataFrame既有行索引也有列索引,他可以被看做是由Series組成的字典(共用同一個索引)
跟其他類似的數據結構相比,DataFrame中面向行和面向列的操作基本上是平衡的。
DataFrame 是以二維數據結構保存數據的
構建DataFrame
最常用的一種是直接傳入一個有等長列表或Numpy數組組成的字典
In [2]: data = {"state": ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada'], 'year':[2000, 2001, 2002, 2001, 2002], 'pop':[1.5, 1.7, 3.6, 2.4, 2.9]} In [3]: from pandas import Series, DataFrame In [4]: DataFrame(data) Out[4]: pop state year 0 1.5 Ohio 2000 1 1.7 Ohio 2001 2 3.6 Ohio 2002 3 2.4 Nevada 2001 4 2.9 Nevada 2002
另一種嵌套字典生成DataFrame
In [29]: pop = {'Nevada': {2001:2.4, 2003:2.9}, 'Ohio':{2000:1.5, 2001:1.7, 2002:3.6}} In [30]: frame3 = Dataframe(pop) --------------------------------------------------------------------------- NameError Traceback (most recent call last) <ipython-input-30-da7c61f3c94a> in <module>() ----> 1 frame3 = Dataframe(pop) NameError: name 'Dataframe' is not defined In [31]: frame3 = DataFrame(pop) In [32]: frame3 Out[32]: Nevada Ohio 2000 NaN 1.5 2001 2.4 1.7 2002 NaN 3.6 2003 2.9 NaN
第三種:
>>> d = [{"a":1,"b":2}, {"b":1,"a":2}] >>> D = DataFrame(d)
>>> D
a b
0 1 2
1 2 1
第四種
In [52]: data = DataFrame(np.arange(16).reshape((4,4)), index=["Ohio", "Colorado", "Utah", "New York"], columns=["one", "two", "three", "four"]) In [53]: data Out[53]: one two three four Ohio 0 1 2 3 Colorado 4 5 6 7 Utah 8 9 10 11 New York 12 13 14 15
DataFrame 的列按照順序進行排列(列排序)
In [6]: DataFrame(data, columns=['year', 'state', 'pop']) In [7]: data Out[7]: year state pop 0 2000 Ohio 1.5 1 2001 Ohio 1.7 2 2002 Ohio 3.6 3 2001 Nevada 2.4 4 2002 Nevada 2.9
跟Series一樣,如果傳入的列在數據中找不到, 就會產生NA值
In [11]: frame2 = DataFrame(data, columns=['year', 'state', 'pop', 'debt'], index=['one', 'two', 'three', 'four', 'five']) In [12]: frame2 Out[12]: year state pop debt one 2000 Ohio 1.5 NaN two 2001 Ohio 1.7 NaN three 2002 Ohio 3.6 NaN four 2001 Nevada 2.4 NaN five 2002 Nevada 2.9 NaN
axis=0和1分別的表格的縱軸和橫軸
通過字典標記(索引)的方式獲取一個Series
In [13]: frame2['year'] 也可以寫成frame2.year Out[13]: one 2000 two 2001 three 2002 four 2001 five 2002 Name: year, dtype: int64
返回的Series擁有同樣的索引
行也可以通過位置或名稱的方式進行獲取,例如用索引字段ix
In [14]: frame2.ix['three'] Out[14]: year 2002 state Ohio pop 3.6 debt NaN Name: three, dtype: object
索引賦值
In [23]: df2.loc['d'] = [i*0 for i in range(len(df2.columns))] In [24]: df2 Out[24]: b d e dd Uhahdd 0.0 1.0 2.0 0 Ohiodd 3.0 4.0 5.0 0 Texasdd 6.0 7.0 8.0 0 Oregondd 9.0 10.0 11.0 0 dd 1.0 2.0 3.0 4 d 0.0 0.0 0.0 0
列表推到式還可以寫成
map(lambda x:0 if x >0 else 0, a)
列賦值
列可以通過賦值的方式進行修改。例如我們可以給那個空的‘debt’列附上一個附上一個標量或一組值
In [15]: frame2['debt'] = 16.5 In [16]: frame2 Out[16]: year state pop debt one 2000 Ohio 1.5 16.5 two 2001 Ohio 1.7 16.5 three 2002 Ohio 3.6 16.5 four 2001 Nevada 2.4 16.5 five 2002 Nevada 2.9 16.5
In [17]: import numpy as np In [18]: frame2['debt'] = np.arange(5.) In [19]: frame2 Out[19]: year state pop debt one 2000 Ohio 1.5 0.0 two 2001 Ohio 1.7 1.0 three 2002 Ohio 3.6 2.0 four 2001 Nevada 2.4 3.0
將一個列表或數組賦值給某個列時, 如果賦值的是Series, 就會精確匹配DataFrame的索引,
所有的空值將會被填上缺失值。
n [20]: val = Series([1.2, 1.3, -1.2], index=['two', 'four', 'five']) In [21]: frame2['debt'] = val In [22]: frame2 Out[22]: year state pop debt one 2000 Ohio 1.5 NaN two 2001 Ohio 1.7 1.2 three 2002 Ohio 3.6 NaN four 2001 Nevada 2.4 1.3 five 2002 Nevada 2.9 -1.2
創建列
可以創建新列
In [23]: frame2['eastern'] = frame2.state == 'Ohio' In [24]: frame2 Out[24]: year state pop debt eastern one 2000 Ohio 1.5 NaN True two 2001 Ohio 1.7 1.2 True three 2002 Ohio 3.6 NaN True four 2001 Nevada 2.4 1.3 False five 2002 Nevada 2.9 -1.2 False
刪除列
In [26]: del frame2['eastern'] In [27]: frame2 Out[27]: year state pop debt one 2000 Ohio 1.5 NaN two 2001 Ohio 1.7 1.2 three 2002 Ohio 3.6 NaN four 2001 Nevada 2.4 1.3 five 2002 Nevada 2.9 -1.2
In [28]: frame2.columns
Out[28]: Index([u'year', u'state', u'pop', u'debt'], dtype='object')
結果 行、列倒置,調換位置
In [33]: frame3.T Out[33]: 2000 2001 2002 2003 Nevada NaN 2.4 NaN 2.9 Ohio 1.5 1.7 3.6 NaN
內層字典的鍵會被合並、排序以形成最終的索引。如果顯示指定了索引, 則按照索引走
In [35]: DataFrame(pop, index=[2001, 2002, 2003, 2004]) Out[35]: Nevada Ohio 2001 2.4 1.7 2002 NaN 3.6 2003 2.9 NaN 2004 NaN NaN
也可以根據索引key和切片取值賦值
In [36]: pdata = {'Ohio': frame3['Ohio'][:-1], 'Nevada': frame3['Nevada'][:2]} In [39]: DataFrame(pdata) Out[39]: Nevada Ohio 2000 NaN 1.5 2001 2.4 1.7 2002 NaN 3.6
可以輸入給DataFrame構造器的數據
二維ndarray 數據矩陣,還可以傳入行標和列標 由數組、列表和元組組成的字典 每個序列會變成DataFrame的一列。 所有序列的長度必須相同 Numpy的結構化/記錄數組 類似於“由數組組成的字典” 由Series組成的字典 每個Series會成為一列。如果沒有顯示指定索引, 則各Series的索引會被合並成結果的行索引 由字典組成的字典 各內層字典會成為一列。鍵會被合並成結果的行索引,跟"由Series組成的字典"的情況一樣 字典或Series的列表 各項將會成為DataFrame的一行。字典鍵或Series索引的並集將會成為DataFrame的列標 由列標或元組組成的列表 類似於“二維ndarray” 另一個DataFrame 該DataFrame的索引將會被沿用,除非顯示指定了其他索引 Numpy的MaskedArray 類似於"二維ndarray"的情況, 只是掩碼值在結果DataFrame會變成NA/缺失值
行標,列標設置別名
In [40]: frame3.index.name = "year"; frame3.columns.name = "state" In [41]: frame3 Out[41]: state Nevada Ohio year 2000 NaN 1.5 2001 2.4 1.7 2002 NaN 3.6 2003 2.9 NaN
獲取數據
DataFrame以二維ndarray的形式返回數據
In [42]: frame3.values Out[42]: array([[ nan, 1.5], [ 2.4, 1.7], [ nan, 3.6], [ 2.9, nan]])
如果DataFrame各列的數據類型不同, 則值數組的數據類型就會選用能兼容所有列的數據類型
----------------------------------------
索引對象
pandas的索引對象負責管理軸標簽和其他元數據(比如軸名稱等。)構建Series或Data Frame時,所用到的任何數組或其他序列的標簽都會被轉換成一個Index。
In [1]: from pandas import Series, DataFrame In [2]: obj = Series(range(3), index=["a", "b", "c"]) In [3]: index = obj.index In [4]: index Out[4]: Index([a, b, c], dtype=object) In [5]: obj Out[5]: a 0 b 1 c 2 In [6]: index[1:] Out[6]: Index([b, c], dtype=object)
而索引是不可修改的
那么根據上面的例子,報錯,證明索引是不可以修改的
In [7]: index[1] Out[7]: 'b' In [8]: index[1] = "d" --------------------------------------------------------------------------- Exception Traceback (most recent call last) C:\Python27\<ipython-input-8-092906bbf8a9> in <module>() ----> 1 index[1] = "d" C:\Python27\lib\site-packages\pandas\core\index.pyc in __setitem__(self, key, value) 307 def __setitem__(self, key, value): 308 """Disable the setting of values.""" --> 309 raise Exception(str(self.__class__) + ' object is immutable') 310 311 def __getitem__(self, key): Exception: <class 'pandas.core.index.Index'> object is immutable
而這樣做的目的是index對象在多個數據結果之間安全共享
In [11]: index = pd.Index(np.arange(3)) In [12]: index Out[12]: Int64Index([0, 1, 2], dtype=int64) In [13]: obj2 = Series([1.5, -2.5, 0], index=index) In [14]: obj2 Out[14]: 0 1.5 1 -2.5 2 0.0
證明是共享的
In [16]: obj2.index is index
Out[16]: True
pandas中主要的Index對象
Index 最泛化的Index對象, 將軸標簽表示為一個由python對象組成的Numpy數組
Int64Index 針對整數的特殊Index
MultiIdex “層次化”索引對象, 表示單個軸上的多層索引。可以看做由元組組成的數組
DatatimeIndex 存儲納秒級時間戳(用NumPy的datatime64類型表示)
PeriodIndex 針對Period數據(時間jiange)的特殊Index
Index的方法和屬性
append 連接另一個index對象,產生另一個新的Index
diff 計算差集,並得到一個index
intersection 計算交集
union 計算並集
isin 計算一個指示各值是否都包含在參數集合中的布爾型數據
delete 刪除索引i處的元素,bing得到一個新的Index
drop 刪除傳入的值,並得到新的Index
insert 將元素插入到索引i出, 並得到新的index
is_monotonic 當各元素均大於等於前一個元素是,返回True
is_unique 當index沒有重復值時,返回True
unique 計算Index中唯一值的數組
In [42]: index3.delete(2) Out[42]: Int64Index([0, 1, 4, 5, 6], dtype=int64) In [28]: index3 = index.append(Index2) In [29]: index3 Out[29]: Int64Index([0, 1, 2, 4, 5, 6], dtype=int64)
reindex重新索引 (fill_value 設置默認值)
pandas對象的一個重要方法是reindex, 其作用是創建一個適應新索引的新對象。
而調用Series的reindex將會根據新索引進行重排。如果某個索引值不存在,就引入缺失值。
obj = Series([4.5, 7.l2, -5.3, 3.6], index=['d', 'b', 'a', 'c']) In [25]: obj2 = obj.reindex([i for i in list("abcde")], fill_value=0) In [26]: obj2 Out[26]: a -5.2 b 7.2 c 3.6 d 4.5 e 0.0 dtype: float64
但是注意:時間序列這樣的有序數據, 重新索引時可能需要做一些插值處理。method選項即可達到目的
例如使用ffill可以實現向前值填充:
In [27]: obj3 = Series(["blue", "purple", "yellow"], index=[0, 2, 4]) In [28]: obj3.reindex(range(6), method="ffill") Out[28]: 0 blue 1 blue 2 purple 3 purple 4 yellow 5 yellow dtype: object In [29]: obj3 Out[29]: 0 blue 2 purple 4 yellow dtype: object
reindex 可以重新 修改(行)索引、列, 或兩個都可以修改。傳入一個值默認為行索引
In [33]: frame = DataFrame(np.arange(9).reshape((3, 3)), index=[i for i in list('abc')], columns=["Ohio", "Texas", "California"]) In [34]: frame Out[34]: Ohio Texas California a 0 1 2 b 3 4 5 c 6 7 8 In [35]: frame2 = frame.reindex([i for i in list("abcd")]) In [36]: frame2 Out[36]: Ohio Texas California a 0.0 1.0 2.0 b 3.0 4.0 5.0 c 6.0 7.0 8.0 d NaN NaN NaN In [37]: states = ["Texas", "Utah", "California"] In [38]: frame.reindex(columns=states) Out[38]: Texas Utah California a 1 NaN 2 b 4 NaN 5 c 7 NaN 8 In [39]: frame.ix[[i for i in list("abcd")], states] Out[39]: Texas Utah California a 1.0 NaN 2.0 b 4.0 NaN 5.0 c 7.0 NaN 8.0 d NaN NaN NaN
-------------------------------------------------------------------
Series 和 DataFrame 丟棄指定軸上的項 pandas刪除行
丟棄某條軸上的一個或多個項很簡單, 只要偶一個索引數組或列表即可。
而drop方法返回的是一個在指定軸上刪除了指定值的新對象。
In [46]: obj = Series(np.arange(5.), index=[i for i in list("abcde")]) In [47]: obj Out[47]: a 0.0 b 1.0 c 2.0 d 3.0 e 4.0 dtype: float64 In [48]: new_obj = obj.drop("c") In [49]: new_obj Out[49]: a 0.0 b 1.0 d 3.0 e 4.0 dtype: float64 In [50]: obj.drop(["b", "c"]) Out[50]: a 0.0 d 3.0 e 4.0 dtype: float64
而DataFrame可以刪除任意軸上的索引值
In [52]: data = DataFrame(np.arange(16).reshape((4,4)), index=["Ohio", "Colorado", "Utah", "New York"], columns=["one", "two", "three", "four"]) In [53]: data Out[53]: one two three four Ohio 0 1 2 3 Colorado 4 5 6 7 Utah 8 9 10 11 New York 12 13 14 15 In [54]: data.drop(["Colorado", ""Ohio]) File "<ipython-input-54-8d771dda6c46>", line 1 data.drop(["Colorado", ""Ohio]) ^ SyntaxError: invalid syntax In [55]: data.drop(["Colorado", "Ohio"]) Out[55]: one two three four Utah 8 9 10 11 New York 12 13 14 15 ------- In [57]: data.drop(["one"], axis=1) Out[57]: two three four Ohio 1 2 3 Colorado 5 6 7 Utah 9 10 11 New York 13 14 15 In [58]: data.drop(["one", "four"], axis=1) Out[58]: two three Ohio 1 2 Colorado 5 6 Utah 9 10 New York 13 14
---------------------------------------------
索引選取和過濾
Series
Series 索引(obj[...])的工作方式類似與Numpy數組的索引,只不過Series的索引值不只是整數
In [8]: obj = Series(np.arange(4.), index = [i for i in list("abcd")]) In [9]: obj['b'] Out[9]: 1.0 In [10]: obj[1] Out[10]: 1.0 In [11]: obj[2:4] Out[11]: c 2.0 d 3.0 dtype: float64 In [12]: obj[['b', 'c', 'd']] Out[12]: b 1.0 c 2.0 d 3.0 dtype: float64 In [13]: obj[[1, 3]] Out[13]: b 1.0 d 3.0 dtype: float64 In [14]: obj[obj<2] Out[14]: a 0.0 b 1.0 dtype: float64
利用索引賦值
In [15]: obj['b':'c'] Out[15]: b 1.0 c 2.0 dtype: float64 In [16]: obj['b':'c'] = 5 In [17]: obj Out[17]: a 0.0 b 5.0 c 5.0 d 3.0 dtype: float64
DataFrame
而DataFrame進行索引就是獲取一個或多個列, 默認是columns
data【columns, index】的格式

In [18]: data = DataFrame(np.arange(16).reshape((4,4)), index=['Ohio', 'Colorado', 'Utah', 'New York'], columns = ['one', 'two', 'three', 'four']) In [19]: data Out[19]: one two three four Ohio 0 1 2 3 Colorado 4 5 6 7 Utah 8 9 10 11 New York 12 13 14 15 In [20]: data['two'] Out[20]: Ohio 1 Colorado 5 Utah 9 New York 13 Name: two, dtype: int64 In [21]: data[['three', 'one']] Out[21]: three one Ohio 2 0 Colorado 6 4 Utah 10 8 New York 14 12 In [23]: data[:2] Out[23]: one two three four Ohio 0 1 2 3 Colorado 4 5 6 7 In [24]: data[data['three'] > 5] Out[24]: one two three four Colorado 4 5 6 7 Utah 8 9 10 11 New York 12 13 14 15
值為bool類型

In [25]: data < 5 Out[25]: one two three four Ohio True True True True Colorado True False False False Utah False False False False New York False False False False
重新賦值

In [26]: data[data < 5] = 0 In [27]: data Out[27]: one two three four Ohio 0 0 0 0 Colorado 0 5 6 7 Utah 8 9 10 11 New York 12 13 14 15
DataFrame.ix
如果DataFrame 使用標簽索引的話,就是index,需要引入專門的ix,其實就是調換方向
data【index, columns】
In [28]: data.ix['Colorado', ['three']] Out[28]: three 6 Name: Colorado, dtype: int64 In [29]: data.ix[['Colorado', 'Utah'], [3, 0, 1]] Out[29]: four one two Colorado 7 0 5 Utah 11 8 9
Chrome://flags/#enable-smooth-scrolling