iloc:按顺序索引,和dataframe的行号(index)和列名(columns)没有任何关系。
loc:按行号(index)和列名(columns)索引,和顺序没有任何关系。
之所以二者总是分不清,是因为一般情况下,dataframe的index是从0到n的顺序排列,这会导致iloc和loc在某些时候索引出来的结果一致,难以分清二者的差别。一旦dataframe的index和columns都不是数字,那么二者索引的结果是完全不一样的。
用一个例子来看懂,二者的本质差别:
首先,生成一个dataframe,其index和columns都是按序排列的数字。
import pandas as pd
import numpy as np
a = np.arange(12).reshape(4,3)
df = pd.DataFrame(a)
df
df输出结果为:
(一)索引行
此时按行索引,iloc和loc的结果一致,因为index就是和顺序一致的。
# 索引行,iloc和loc的结果一致
print(df.iloc[3])
print(df.loc[3])
输出结果为:
df.iloc[3]输出的是第4行;df.loc[3]输出的是index=3的行;此时index=3就是第4行,所以结果一致。
此时,如果我把行索引的名字改掉,即index重命名,结果还会一致吗?
df.rename(index={0:'a',1:'b',2:'c',3:'d'},inplace=True)
df
df输出结果为:
再重新执行
print(df.iloc[3])
print(df.loc[3])
df.iloc[3]的输出结果不变,仍为:
df.loc[3]则报错,因为找不到index=3的行索引了。
所以,df.iloc[3]无论dataframe索引怎么变化,都会有结果;df.loc[3]只要index没有3了,肯定就报错。
再看列索引...
(二)列索引
索引dataframe的列,需要指定行,“:”代表索引所有行。
接着执行以下程序
print(df.iloc[:,0:2]) # 输出第0,1列
print(df.loc[:,0:2]) # 输出column=0,column=1,column=2列
df.iloc[:,0:2]输出的是所有行,前两列:
df.loc[:,0:2])输出的所有行,前三列:
此时,df.loc[:,0:2]相当于执行的是,df.loc[:,[0,1,2]]:
所以,df.loc[:,0:2]的0:2并不代表顺序索引,而是转化成了对应的列名[0,1,2]。
其实,行索引df.loc[0:2,:],也是执行的df.loc[[0,1,2]:],会比df.iloc[0:2,:]多一行。
所以,当某个dataframe的索引总是数字的时候,iloc和loc总是差了一行,这个非常容易出错。
(三)索引某个元素
如果理解了以上的行索引和列索引,对某个元素的索引就非常好理解了。
当我们的dataframe的index和columns都是按顺序的数字时:
我们用df.iloc[1,1] 和df.loc[1,1],结果都是一样的,都是4。
一旦我们修改dataframe的index和columns:
那么df.iloc[1,1] 索引的结果不变,仍为4。df.loc[1,1]索引到index=1,column=1的元素,结果为0。