索引
单级索引
1.loc方法、iloc方法、[]操作符
loc方法
通过索引访问
(注意:所有在loc中使用的切片全部包含右端点!
单行索引
df.loc[1103]
返回第1103row
多行索引
df.loc[[1102,2304]]
返回第1102,2304row
df.loc[1304:].head()
返回从1304到最后一row
df.loc[2402::-1].head()
df行颠倒输出,从2404输出到第一行,步长为1
单列索引
df.loc[:,‘Height’].head()
返回df[‘Height’]的全部
多列索引
df.loc[:,[‘Height’,‘Math’]].head()
返回这两列
df.loc[:,‘Height’:‘Math’].head()
返回’Height’ 到’Math’的全部列,包括右端点
联合索引
df.loc[1102:2401:3,‘Height’:‘Math’].head()
1102到2401row,步长为3,即两个输出行之间隔2行
函数式索引
df.loc[lambda x:x[‘Gender’]==‘M’].head()
#loc中使用的函数,传入参数就是前面的df
使得x[‘Gender’]=='M’的x传入df
def f(x):
return [1101,1103]
df.loc[f]
返回1101 1103行
布尔索引
df.loc[df[‘Address’].isin([‘street_7’,‘street_4’])].head()
返回这样的行x,x[‘Address’]=s7或s4
df.loc[[True if i[-1]‘4’ or i[-1]‘7’ else False for i in df[‘Address’].values]].head()
df[‘Address’].values 返回的是array
for i in array, 则i是array里的每个值
i[-1]则是值i的最后一位
True if i[-1]==‘4’ or ‘7’, else False如果i最后一位是7或者4,则为True,反之为false,True就会被return
又因为是返回多行,所以两个[] []
本质上说,loc中能传入的只有布尔列表和索引子集构成的列表
iloc方法
通过行和列标访问
(注意与loc不同,切片右端点不包含)
单行索引
df.iloc[3]
返回第四行
如果index为数字,df.loc=df.iloc(仅单行和单列时
df.iloc[3:5]
返回3 4行,不包括右端点
单列索引
df.iloc[:,3].head()
返回第四列,这里还是没有区别
多列索引
df.iloc[:,7::-2].head()
从第8列开始倒着输出到第一,步长为2
混合索引
df.iloc[3::4,7::-2].head()
从第4行到最后,隔3行输出从第8列到第1列,每隔1列输出
函数式索引
df.iloc[lambda x:[3]].head()
为[3]的x传入df,df[3]
由上所述,iloc中接收的参数只能为整数或整数列表,不能使用布尔索引
[]操作符
如果不想陷入困境,请不要在行索引为浮点时使用[]操作符
因为在Series中的浮点[]并不是进行位置比较,而是值比较,非常特殊
Series的[]操作
单元素索引
####### s = pd.Series(df[‘Math’],index=df.index)
s[1101]
#使用的是索引标签
返回Series的index为1101的值
多行索引
####### s[0:4]
#使用的是绝对位置的整数切片,与元素无关,这里容易混淆
Series的第1-4行
函数索引
####### s[lambda x: x.index[16::-6]]
#注意使用lambda函数时,直接切片(如:s[lambda x: 16::-6])就报错
此时使用的不是绝对位置切片,而是元素切片,非常易错
有 Series x,使得x.index从17个到第一个为止,每隔5个index输出一次。将这样的Series传入s
布尔索引
####### s[s>80]
返回新的Series,其中包含所有值都是s中大于80的值
DataFrame的[]操作
单行索引
####### df[1:2]
f[]和df.loc,df.iloc一样,默认的index都是行索引
因此此处返回的是df的第二行
####### row = df.index.get_loc(1102)
df[row:row+1]
如果想要获得某一个元素,可用get_loc方法
多行索引
####### df[3:5]
用切片,如果是选取指定的某几行,推荐使用loc,否则很可能报错
单列索引
####### df[‘School’].head()
多列索引
####### df[[‘School’,‘Math’]].head()
和df.loc的多行索引一样,都需要加俩[][]
函数式索引
####### df[lambda x:[‘Math’,‘Physics’]].head()
布尔索引
####### df[df[‘Gender’]==‘F’].head()
一般来说,[]操作符常用于列选择或布尔选择,尽量避免行的选择
布尔索引
布尔符号:& - and, | - or, ~ - not 取反
df[(df[‘Gender’]‘F’)&(df[‘Address’]‘street_2’)].head()
df[(df[‘Math’]>85)|(df[‘Address’]==‘street_7’)].head()
df[~((df[‘Math’]>75)|(df[‘Address’]==‘street_1’))].head()
Math小于等于75并且Address不等于s1
df.loc[df[‘Math’]>60,(df[:8][‘Address’]==‘street_6’).values].head()#
如果不加values就会索引对齐发生错误,Pandas中的索引对齐是一个重要特征,很多时候非常使用
但是若不加以留意,就会埋下隐患
df.loc[]中有两个值,第一个为布尔列表,第二个为列表
布尔列表:Math>60,或者
前9行里Address=s1的array
isin方法
df[df[‘Address’].isin([‘street_1’,‘street_4’])&df[‘Physics’].isin([‘A’,‘A+’])]
如果只有内行df,则返回的类型是Series,df[Series]>>>DataFrame
#上面也可以用字典方式写:
df[df[[‘Address’,‘Physics’]].isin({‘Address’:[‘street_1’,‘street_4’],‘Physics’:[‘A’,‘A+’]}).all(1)]
#all与&的思路是类似的,其中的1代表按照跨列方向判断是否全为True
快速标量索引
当只需要取一个元素时,at和iat方法能够提供更快的实现
display(df.at[1101,‘School’])
display(df.loc[1101,‘School’])
display(df.iat[0,0])
display(df.iloc[0,0])
区间索引
利用interval_range方法
pd.interval_range(start=0,end=5)
#closed参数可选’left’‘right’‘both’‘neither’,默认左开右闭
pd.interval_range(start=0,periods=8,freq=5)
#periods参数控制区间个数,freq控制步长
利用cut将数值列转为区间为元素的分类变量
例如统计数学成绩的区间情况
math_interval = pd.cut(df[‘Math’],bins=[0,40,60,80,100])
#注意,如果没有类型转换,此时并不是区间类型,而是category类型
math_interval.head()
区间索引的选取
df_i = df.join(math_interval,rsuffix=’_interval’)[[‘Math’,‘Math_interval’]]\
.reset_index().set_index('Math_interval')
df.join(新加Series), 参数rssufix: 从右框架覆盖列中使用后缀
因为Math_interval还是来源于df[Math’]的,所以算是overlapping吧
是rsuffix而不是lsuffix说明新加的Series在左而df在右
df[[’’,’’]]选取了df的这两列展示
reset_index()det_index(’ ') 把这个新的df的其中一列(暂时)设置成index,对原有df不产生影响
/.另起一行,是为了避免一行代码写太长,没有其他影响
df_i.loc[65].head()重新设置好index之后,用65进行新的index查找,会返回所有区间含有65这个数字的行
df_i.loc[[65,90]].head()
区间含有65或者90的行