上篇文章介紹了Pandas的基礎操作,包括文件讀寫、Series和DataFrame數據結構、一些常用基本函數、數據排序等。
今天我們來學習一下Pandas的索引。
(超詳細!一文搞定!)
Pandas單級索引
1. loc、iloc、[]操作符
這三類最常用的索引方法,其中iloc表示位置索引,loc表示標簽索引,[]也具有很大的便利性,各有特點。
總結來說就是:
- loc只能傳布爾列表或索引列表
- iloc只能傳整數列表
1.1 loc方法
- 本質上來說,loc中能傳入的只有布爾列表和索引子集構成的列表。
- loc方法包含切片右端點。
# 單行索引
dataframe.loc[index]
# 多行索引
dataframe.loc[index1, index2]
dataframe.loc[index: ]
dataframe.loc[開始:結束:步長]
# 多列索引
dataframe[:, '列索引名']
# 函數式索引(傳入的參數是dataframe)
dataframe.loc[lambda x:x['Gender']=='M']
def f(x):
return [1101,1103]
df.loc[f]
1.2 iloc方法
- iloc中接收的參數只能為整數或整數列表,不能使用布爾索引
- iloc方法不包含切片右端點。
# 單行索引
df.iloc[3]
#多行索引
df.iloc[3:5]
# 單列索引
df.iloc[:,3]
# 多列索引
df.iloc[:,7::-2]
# 函數式索引
df.iloc[lambda x:[3]]
1.3 []操作符
- 在Series中的浮點[]並不是進行位置比較,而是值比較,因此不要在行索引為浮點時使用[]操作符。
- []操作符常用於列選擇或布爾選擇,盡量避免行的選擇
(1) Series的[]操作符
s = pd.Series(df['Math'],index=df.index)
# 單元素索引
s[1101]
# 多行索引
s[0:4]
# 函數式索引
s[lambda x: x.index[16::-6]]
# 布爾索引
s[s>80]
(2) DataFrame的[]操作符
# 單行索引
df[1:2]
row = df.index.get_loc(1102) # get_loc()返回索引值(所在的行號)
df[row:row+1]
# 多行操作
df[3:5] # 切片
# 單列索引
df['School']
# 多列索引
df[['School','Math']]
# 函數式索引
df[lambda x:['Math','Physics']]
2. 布爾索引
2.1 布爾符號:'&', '|', '~',分別代表 和and,或or,非not
df[(df['Gender']=='F')&(df['Address']=='street_2')]

df[(df['Math']>85)|(df['Address']=='street_7')].head()

df[~((df['Math']>75)|(df['Address']=='street_1'))]

2.2 isin方法
df[df['Address'].isin(['street_1','street_4'])&df['Physics'].isin(['A','A+'])]
# 字典方式
df[df[['Address','Physics']].isin({'Address':['street_1','street_4'],'Physics':['A','A+']}).all(1)]
#all與&的思路是類似的,其中的1代表按照跨列方向判斷是否全為True

3 標量索引
at和iat方法,適用於只取一個元素的情況。
同樣,at只能傳布爾列表或索引列表,iat只能傳整數列表
df.at[1101,'School']
df.iat[0,0]
4 區間索引
(1) interval_range方法:
#closed參數可選'left''right''both''neither',默認左開右閉
pd.interval_range(start=0,end=5)
# periods參數控制區間個數,freq控制步長
pd.interval_range(start=0,periods=8,freq=5)
下面用一個具體的例子——統計數學成績的區間情況,來說明區間索引。
math_interval = pd.cut(df['Math'],bins=[0,40,60,80,100])
df_i = df.join(math_interval,rsuffix='_interval')[['Math','Math_interval']].reset_index().set_index('Math_interval')
df_i.head()

df_i.loc[90] # 會選中該值的區間
如果想要選取某個區間,先要把分類變量轉為區間變量,再使用overlap方法:
df_i[df_i.index.astype('interval').overlaps(pd.Interval(70, 85))].head()

Pandas多級索引
1 多層索引的創建
多層索引的創建主要有三類方法:
- from_tuple或from_arrays
- from_product
- 指定dataframe的列創建(set_index方法)
下面分別舉例說明。
1.1 from_tuple或from_arrays
# 直接創建
tuples = [('A','a'),('A','b'),('B','a'),('B','b')]
mul_index = pd.MultiIndex.from_tuples(tuples, names=('Upper', 'Lower'))
pd.DataFrame({'Score':['perfect','good','fair','bad']},index=mul_index)
# 利用zip
L1 = list('AABB')
L2 = list('abab')
tuples = list(zip(L1,L2))
mul_index = pd.MultiIndex.from_tuples(tuples, names=('Upper', 'Lower'))
pd.DataFrame({'Score':['perfect','good','fair','bad']},index=mul_index)
# 通過array
arrays = [['A','a'],['A','b'],['B','a'],['B','b']]
mul_index = pd.MultiIndex.from_tuples(arrays, names=('Upper', 'Lower'))
pd.DataFrame({'Score':['perfect','good','fair','bad']},index=mul_index)

通過打印mul_index可以看出,上述三種方式都是通過內部自動轉換成元組來創建的。
1.2 from_product
L1和L2兩兩相乘
L1 = ['A','B']
L2 = ['a','b']
pd.MultiIndex.from_product([L1,L2],names=('Upper', 'Lower'))
1.3 指定dataframe的列(set_index方法)
df_using_mul = df.set_index(['Class','Address'])
df_using_mul.head()

2 多層索引切片
這里舉例都是用上一小節的df_using_mul做演示。
(1)一般切片
# 當索引不排序時,不能使用多層切片
df_using_mul.sort_index().loc['C_2','street_5']
df_using_mul.sort_index().loc[('C_2','street_6'):('C_3','street_4')]
df_using_mul.sort_index().loc[('C_2','street_7'):'C_3'].head()
(2)第一類特殊情況:由元組構成列表
df_using_mul.sort_index().loc[[('C_2','street_7'),('C_3','street_2')]]
# 表示選出某幾個元素,精確到最內層索引
第二類特殊情況:由列表構成元組
df_using_mul.sort_index().loc[(['C_2','C_3'],['street_4','street_7']),:]
# 選出第一層在‘C_2’和'C_3'中且第二層在'street_4'和'street_7'中的行
3 多層索引的slice對象
L1,L2 = ['A','B','C'],['a','b','c']
mul_index1 = pd.MultiIndex.from_product([L1,L2],names=('Upper', 'Lower'))
L3,L4 = ['D','E','F'],['d','e','f']
mul_index2 = pd.MultiIndex.from_product([L3,L4],names=('Big', 'Small'))
df_s = pd.DataFrame(np.random.rand(9,9),index=mul_index1,columns=mul_index2)
idx=pd.IndexSlice

索引Slice的使用非常靈活,可以很方便地對索引進行操作。
結果如下:索引取了B后面的、D d>0.3的、縱向求和>4的部分。
df_s.loc[idx['B':,df_s['D']['d']>0.3],idx[df_s.sum()>4]]

4 索引層交換
主要有兩個方法:
- swaplevel方法:用於兩層交換
- recorder_levels方法:用於多層交換
# swaplevel方法
df_using_mul.swaplevel(i=1,j=0,axis=0).sort_index()
# recorder_levels方法
df_muls = df.set_index(['School','Class','Address'])
df_muls.reorder_levels([1,2,0],axis=0).sort_index()
#如果索引有name,可以直接使用name
df_muls.reorder_levels(['Class','Address','School'],axis=0).sort_index()

索引設定
這部分所講的是索引設定的一些操作。
(1)index_col參數
在使用read_csv函數時,通過index_col可以設定索引。
(2)reindex和reindex_like
- reindex是指重新排序。重要特性在於索引對齊,很多時候用於重新排序。
#bfill表示用所在索引的后一個有效行填充,ffill為前一個有效行,nearest是指最近的
df.reindex(index=[1101,1203,1206,2402], columns=['Height','Gender','Average'], method='bfill')
- reindex_like的作用為生成一個橫縱索引完全與參數列表一致的DataFrame,數據使用被調用的表。如果表是單調的還可以使用method參數。
df_temp = pd.DataFrame({'Weight':range(5),
'Height':range(5),
'ID':[1101,1104,1103,1106,1102]}).set_index('ID').sort_index()
df_temp.reindex_like(df[0:5][['Weight','Height']],method='bfill')
#可以自行檢驗這里的1105的值是否是由bfill規則填充

(3)set_index和reset_index
- 使用set_index時,將某些列作為索引。指定參數
append=True可以維持當前索引不變 - reset_index將索引重置。默認狀態直接恢復到自然數索引
(4)rename_axis和rename
- rename_axis是針對多級索引的方法,作用是修改某一層的索引名,而不是索引標簽。
- rename方法用於修改列或者行索引標簽,而不是索引名。
df_temp.rename_axis(index={'Lower':'LowerLower'},columns={'Big':'BigBig'})
df_temp.rename(index={'A':'T'},columns={'e':'changed_e'})
常用索引型函數
1 where()和mask()
- where()函數對條件為False的單元進行填充,第一個參數為布爾條件,第二個參數為填充值。
- mask()函數對條件為True的單元進行填充,其余完全一致。
# where
df.where(df['Gender']=='M',np.random.rand(df.shape[0],df.shape[1]))
# mask
df.mask(df['Gender']=='M',np.random.rand(df.shape[0],df.shape[1]))
2 query()函數
query函數中的布爾表達式中,行列索引名、字符串、and/not/or/&/|/~/not in/in/==/!=、四則運算符等都是合法的
df.query('(Address in ["street_6","street_7"])&(Weight>(70+10))&(ID in [1303,2304,2402])')

重復元素處理(duplicated和drop_duplicates)
- duplicated方法:
- 返回是否重復的布爾列表。
- 可選參數
keep默認為first,即首次出現設為不重復; - 若為
last,則最后一次設為不重復; - 若為
False,則所有重復項為False。
- drop_duplicates方法:
- 參數與duplicated方法類似。
- 在傳入多列時等價於將多列共同視作一個多級索引,比較重復項。
df.duplicated('Class',keep='last')
df.drop_duplicates('Class',keep='last')
df.drop_duplicates(['School','Class'])
抽樣函數(sample)
- n:樣本量
- frace為抽樣比
- replace為是否放回,
True或者False - axis為抽樣維度,默認為0,即抽行
- weights為樣本權重,自動歸一化。也可以以某一列為權重。
如什么問題,歡迎留言交流,覺得有用的小伙伴順手點個贊吧。
你的肯定是我的最大動力!
