Pandas數據處理
保留索引
NumPy的通用函數(三角函數、指數函數、對數函數等)是適用於Pandas的Series和DataFrame對象。當在兩個Series或DataFrame對象上進行二元計算時,Pandas會在計算過程中對齊兩個對象的索引。
Series索引對齊
A=pd.Series([2,4,6],index=[0,1,2])
B=pd.Series([1,3,5],index=[1,2,3])
A+B
DataFrame索引對齊
#random.RandomState(0)爲隨機數產生器的種子,裏面的數字相同,則產生的隨機數相同
rng=np.random.RandomState(42)
A=pd.DataFrame(rng.randint(0,20,(2,2)),columns=list('AB'))
B=pd.DataFrame(rng.randint(0,10,(3,3)),columns=list('BAC'))
A+B
兩個對象的行索引可以是不同順序的,結果的索引會自動按順序排列。可以通過運算符fill_value參數自定義缺失值。將用A中所有值的均值來填充缺失值(計算A的均值需要用stack將二維數組壓縮成一維數組)
fill=A.stack().mean()
A.add(B,fill_value=fill)
Python運算符與Pandas方法的映射關係
python運算符 | Pandas方法 |
---|---|
+ | add() |
- | sub()、subtract() |
* | mul()、multiply() |
/ | div() |
// | floordiv() |
% | mod() |
** | pow() |
DataFrame與Series的運算
二維數組減自身的一行數據會按行計算,在Pandas裏默認也是按行運算的
A=rng.randint(10,size=(3,4))
A-A[0]
df=pd.DataFrame(A,columns=list('ABCD'))
df-df.iloc[0]
想按列計算,通過axis參數設置
df.subtract(df['B'],axis=0)
處理缺失值
缺失值主要有三種形式:null、NaN或NA
識別缺失值的方法,可以分爲兩種:一種方法通過一個覆蓋全局的掩碼錶示缺失值,掩碼可能是一個與原數組維度相同的完整布爾類型數組,也可能是用一個比特(0或1)表示有缺失值的局部狀態,另一種方法是用一個標籤值(-999,NaN)表示缺失值。
Pandas最終選擇用標籤方法表示缺失值,包括兩種Python原有的缺失值:浮點數據類型的NaN值、以及Python的None對象。
(1)None:Python對象類型的缺失值
None是一個Python對象,不能作爲任何NumPy/Pandas數組類型的缺失值,只能用於’object’數組類型
dtype=object表示NumPy認爲這個數組是Python對象構成的,對包含None的數組進行累計操作,會出現類型錯誤,python中沒有定義整數與None之間的加法運算。
(2)NaN:數值類型的缺失值,NaN是一種特殊的浮點數
缺失值標籤NaN是一種按照浮點數標準設計、在任何系統中都兼容的特殊浮點數,和NaN進行何種操作,最終結果都是NaN
NumPy也提供了特殊的累計函數,可以忽略缺失值的影響
np.nansum(val),np.nanmin(val),np.nanmax(val)
Pandas中NaN與None
Pandas會將沒有標籤值的數據類型自動轉換爲NA,還會將None轉換爲NaN
處理缺失值
isnull():創建一個布爾類型的掩碼標籤缺失值
notnull():與isnull()操作相反
dropna():返回一個剔除缺失值的數據
fillna():返回一個填充了確實值的數據副本
data=pd.Series([1,np.nan,'hello',None])
data.isnull()
布爾類型掩碼數組可以直接作爲Series或DataFrame的索引使用
data[data.notnull()]
剔除缺失值
dropna()會剔除任何包含缺失值的整行數據,可以設置不同的座標軸剔除缺失值,比如axis=1會剔除任何包含缺失值的整列數據,可以通過how或thresh參數設置剔除行或列缺失值的數量闕值,設置how=‘any’,只要有缺失值就剔除整行或整列,設置how=‘all’,剔除全部是缺失值的行或列了,通過thresh參數設置行或列中非缺失值的最小數量。
df=pd.DataFrame([[1,np.nan,2,np.nan],[2,3,5,np.nan],[np.nan,4,6,np.nan]])
#按照列刪除
df.dropna(axis=1)
df.dropna(axis='columns',how='all')
df.dropna(axis='rows',thresh=3)
填充缺失值
pandas提供了fillna()方法,將返回填充了缺失值後的數組副本。用單獨的值填充缺失值,可以用缺失值前面的有效值來從前往後填充(forward-fill),從後往前填充(back-fill),DataFrame的操作方法與Series類似,只是在填充時需要設置座標軸參數axis,按列填充axis=1,按行填充axis=0
#按列填充
df.fillna(method='ffill',axis=1)
#按行填充
df.fillna(method='ffill',axis=0)
層級索引
通過python元祖構成多級索引
index=[('安徽',2010),('安徽',2011),('江蘇',2010),('江蘇',2011),('浙江',2010),('浙江',2011)]
populations=[20000,25000,30000,35000,40000,45000]
pop=pd.Series(populations,index=index)
Pandas多級索引
index=[('安徽',2010),('安徽',2011),('江蘇',2010),('江蘇',2011),('浙江',2010),('浙江',2011)]
index=pd.MultiIndex.from_tuples(index)
populations=[20000,25000,30000,35000,40000,45000]
pop=pd.Series(populations,index=index)
前兩列表示Series的多級索引值,第三列是數據,可以直接用第二個索引獲取2010年的全部數據
pop[:,2010]
高維數據的多級索引
可以用帶行列索引的簡單DataFrame代替前面的多級索引,unstack()方法可以快速將一個多級索引的Series轉化爲普通索引的DataFram,stack()方法實現相反效果
可以用含多級索引的一維Series數據表示二維數據,就可以用Series或DataFrame表示三維甚至更高維度的數據。多級索引每增加一級,就表示數據增加一維,利用這一特點可以輕鬆表示任意維度的數據了。
index=[('安徽',2010),('安徽',2011),('江蘇',2010),('江蘇',2011),('浙江',2010),('浙江',2011)]
index=pd.MultiIndex.from_tuples(index)
populations=[20000,25000,30000,35000,40000,45000]
pop=pd.Series(populations,index=index)
pop_df=pd.DataFrame({'total':pop,'under18':[20000,30000,40000,50000,60000,70000]})
通用函數或者其他功能同樣適用於層級索引,可以計算18歲以下人口占總人口的比例
f_u18=pop_df['under18']/pop_df['total']
f_u18.unstack()
多級索引的創建辦法
爲Series或DataFrame創建多級索引最直接的辦法就是將index參數設置爲至少二維的索引數組
df=pd.DataFrame(np.random.rand(4,2),index=[['a','a','b','b'],[1,2,1,2]],columns=['data1','data2'])
(1)顯示地創建多級索引
pd.MultiIndex中的類方法可以更加靈活地構建多級索引。
可以通過一個若干簡單數組組成的列表來構建MultiIndex
pd.MultiIndex.from_arrays([['a','a','b','b'],[1,2,1,2]])
可以通過包含多個索引值的元組構成的列表創建MultiIndex
pd.MultiIndex.from_tuples([('a',1),('a',2),('b',1),('b',2)])
在創建Series或DataFrame時,可以將這些對象作爲index參數,或者通過reindex方法更新Series或DataFrame的索引。
(2)多級索引的等級名稱
可以在MultiIndex構造器中通過names參數設置等級名稱
index=[('安徽',2010),('安徽',2011),('江蘇',2010),('江蘇',2011),('浙江',2010),('浙江',2011)]
index=pd.MultiIndex.from_tuples(index)
populations=[20000,25000,30000,35000,40000,45000]
pop=pd.Series(populations,index=index)
pop.index.names=['省份','年份']
(3)多級列索引
既可以有多級行索引,也可以有多級列索引
index=pd.MultiIndex.from_product([['安徽','江蘇','浙江'],[2010,2011]],names=['省份','年份'])
columns=pd.MultiIndex.from_product([['人數','收入','人均收入'],['男','女']],names=['經濟指標','性別'])
#模擬數據
data=np.round(np.random.randn(6,6),1)+100
pop=pd.DataFrame(data,index=index,columns=columns)
如下所示,創建了簡單的四維數據
Series多級索引
通過對多個索引值獲取單個元素
pop['安徽',2011]
MultiIndex支持局部取值,只取索引的某一個層級,獲得的結果是一個新的Series,未被選中的低層索引值會被保留
pop['安徽']
第一級的索引可以用空切片,可以用較低層級的索引取值
pop[:,2011]
DataFrame多級索引
DataFrame的基本索引是列索引
pop['收入','男']
loc、iloc和ix索引器都可以使用,在loc和iloc中可以傳遞多個層級的索引元組
pop.loc[:,('收入','男')]
索引的設置與重置
DataFrame的set_index函數會將其一個或多個列轉換爲行索引,並創建一個新的DataFrame,reset_index的功能是把層級化索引的級別轉移到列裏面
index=[('安徽',2010),('安徽',2011),('江蘇',2010),('江蘇',2011),('浙江',2010),('浙江',2011)]
index=pd.MultiIndex.from_tuples(index,names=['省份','年份'])
populations=[200000,250000,300000,350000,400000,450000]
pop=pd.Series(populations,index=index)
pop_flat=pop.reset_index(name='population')
pop_flat.set_index(['省份','年份'])
排序和排名
根據條件對數據集排序也是一種重要的內置運算,要對行或列索引進行排序,可使用sort_index方法,將返回一個已排序的新對象
obj=pd.Series(range(4),index=['d','a','b','c'])
obj.sort_index()
對於DataFrame可以根據任意一個軸上的索引進行排序
frame=pd.DataFrame(np.arange(8).reshape((2,4)),index=['three','one'],columns=['d','a','b','c'])
frame.sort_index()
frame.sort_index(axis=0)
frame.sort_index(axis=1)
在DataFrame上,根據一個或多個列中的值進行排序,將一個或多個列的名字傳遞給by選項即可
frame=pd.DataFrame({'b':[4,7,-3,2],'a':[0,3,1,4]})
frame.sort_values(by='b')
frame.sort_values(by=['a','b'])
排名會增設一個排名值
#按值在原始數據中的出現順序分配排名
obj=pd.Series([7,-5,7,4,2,0,4])
obj.rank(method='first')