首先,让我们创建一个DataFrame对象,后续的操作均在该数组上进行
df = pd.DataFrame(np.random.randn(6, 4), index=dates, columns=list("ABCD"))
# A B C D
# a -1.622668 0.980099 -0.161964 0.714481
# b 0.784874 -0.301878 -0.117516 -0.804685
# c 0.696801 0.738067 -1.544013 0.628773
# d -0.552270 0.533423 0.417096 -0.130575
# e -0.181280 -1.265713 0.474774 2.083330
# f -0.701355 0.263040 -0.776085 -0.749123
行选择
单行选择
使用 [ ]
+:
操作符组合
[]
常用于数组的选择,:
常用于对数组进行切片处理,通过指定连续的切片区间就可以获得单行选择效果,返回值是一个新的DataFrame对象。注意,使用此种方式时,:
左右两边需要指定的是行的位置,不能提供行索引,此外不能直接通过指定行位置的方式选择,如df[0]
是无法选择第0行的,此种操作会报错,如果传入的是索引而非位置,则会被认为是列索引,而不会被当成行索引
row_1 = df[0:1] # 此处选择得是df的第0行
print(row_1)
# 输出结果为:
# A B C D
# a -1.622668 0.980099 -0.161964 0.714481
使用df.loc[]
df.loc
属性用于根据标签选择行,标签也就是df
的index
属性,与上述方法不同之处在于该属性返回的是一个Series对象,Series对象的索引为原DataFrame对象的columns
属性
row_2 = df.loc['b']
# row_2的值为:
# A 0.784874
# B -0.301878
# C -0.117516
# D -0.804685
# Name: b, dtype: float64
使用df.iloc
df.iloc
属性用于根据位置进行索引,此处的位置表示哪一行,哪一列,例如0表示第0行,1表示第一行,并且只接受位置信息,不接受标签信息,如同df.loc
只接受标签信息不接受位置信息。和df.loc
相同的是返回的是一个Series对象。
row_1 = df.iloc[0] # 选择第0行,返回的是一个Series对象
# row_1的值为:
# A -1.622668
# B 0.980099
# C -0.161964
# D 0.714481
# Name: a, dtype: float64
使用df.A
其中A
是DataFrame中columns中的列索引名,通过这种方式可以直接获取DataFrame中的名称为'A'
的列
多行选择
使用 [ ]
+:
操作符组合
与上述单行选择时不同,当指定的切片区间为连续的多行时,可以达到多行选择的目的,同样,此方式返回的是一个DataFrame对象,需要注意的是索引包左不包右,如下代码所示:
row_0to2 = df[0:2] # 选择第0行、第1行,不选择第2行
# row_0to2的结果为:
# A B C D
# a -1.622668 0.980099 -0.161964 0.714481
# b 0.784874 -0.301878 -0.117516 -0.804685
使用df.loc
当对索引使用:
切片操作时,返回的就会是一个多行的选择结果,与df.loc
进行单行选择不同,多行选择返回的是一个DataFrame,其实在单行选择中也可以使用切片选择,只不过:
左右的切片索引是相同的,如下方代码中所示,这种情况下返回的也是一个DataFrame。其实,总结来说,只要使用了:
切片操作,无论选择的结果是单行还是多行,结果都是一个DataFrame。另外需要注意的一点是:使用基于索引的选择时,选择范围为:
左侧的索引对应的行到右侧对应的行,即左右都包含在结果当中,而使用基于位置的索引时,右侧的行不包括在结果当中。另外也可以使用一个包含行索引的列表来选择多行数据,这种情况下可以选择非连续的多行,但不能传入元组,只能是列表
# 索引'c'对应的行也包含在结果当中
row_a2c = df.loc['a':'c']
# row_a2c的值为:
# A B C D
# a -1.622668 0.980099 -0.161964 0.714481
# b 0.784874 -0.301878 -0.117516 -0.804685
# c 0.696801 0.738067 -1.544013 0.628773
# 传入一个包含行索引的列表
row_ac = df.loc[['a', 'c']]
# row_ac的值为:
# A B C D
# a -1.622668 0.980099 -0.161964 0.714481
# c 0.696801 0.738067 -1.544013 0.628773
# 使用:操作符实现单行选择
row_a = df.loc['a':'a']
# row_a的值为:
# A B C D
# a -1.622668 0.980099 -0.161964 0.714481
使用df.iloc
两者结合使用的方式同上述df.loc
,不同的是df.iloc
使用的是位置而非索引,且:
右侧对应的行不包含在结果当中。此外同上述阐述中所描述的那样,此种方式也可以实现单行选择且返回的是一个DataFrame,具体实现相信也都能够成竹于胸,不在赘述,此外也可以传入一个包含行位置的列表
# 选择第0行和第1行,不包括第2行
row0to2 = df.iloc[0:2]
# row0to2的值为:
# A B C D
# a -1.622668 0.980099 -0.161964 0.714481
# b 0.784874 -0.301878 -0.117516 -0.804685
列选择
单列选择
使用[]
使用[]
的方式进行单行选择时,其使用方法与python中字典根据键获取值的方式完全相同,只不过此处的键需要是DataFrame对象的columns属性中的值,即列索引,返回的是一个Series对象
# 选取列索引为'B'的列
col_B = df['B']
# col_B的值为:
# a 0.980099
# b -0.301878
# c 0.738067
# d 0.533423
# e -1.265713
# f 0.263040
# Name: B, dtype: float64
使用df.loc
使用df.loc
进行单列选择时,首先需要选中所有的行,然后选择需要的列,此种方式类似于numpy中的多维数组选择方式,多个维度选择之间使用','
隔开,:
左右均不指定值时表示选择所有行/列,如下代码所示。需要注意的是,虽然这种方式同时设计到了行选和列选,但返回值是一个Series对象而非一个DataFrame,如果需要返回值是一个DataFrame,则需要使用df.loc[:, 'B':'B']
# 选择类索引为'B'的列
col_B = df.loc[:, 'B']
# col_B的值为:
# a 0.980099
# b -0.301878
# c 0.738067
# d 0.533423
# e -1.265713
# f 0.263040
# Name: B, dtype: float64
使用df.iloc
df.iloc的使用方式同上,区别在与传入的是位置而非索引,两者之间的区别在上面的案例中已经有所提及,返回值可以是一个Series,也可以是一个DataFrame,具体看列选时是否使用:
切片操作符
# 如果是df.iloc[:, 1:2],则返回值是一个DataFrame
col_b = df.iloc[:, 1]
# col_b的值为:
# a 0.980099
# b -0.301878
# c 0.738067
# d 0.533423
# e -1.265713
# f 0.263040
# Name: B, dtype: float64
多列选择
使用[]
使用[]
进行多列选择时,需要传入一个包含列索引的列表,注意,不能是元组,多列选择时,得到的是一个DataFrame,下述多列选择方式也不例外
col_ab = df.[['A', 'B']]
# col_ab的值为:
# A B
# a -1.622668 0.980099
# b 0.784874 -0.301878
# c 0.696801 0.738067
# d -0.552270 0.533423
# e -0.181280 -1.265713
# f -0.701355 0.263040
使用df.loc
使用df.loc
进行多列选择时,首先需要选择所有行,然后进行列选,列选时可以使用切片操作符:
、包含列索引的列表两种方式
col_A2C = df.loc[:, 'A':'C']
# col_A2C的值为:
# A B C
# a -1.622668 0.980099 -0.161964
# b 0.784874 -0.301878 -0.117516
# c 0.696801 0.738067 -1.544013
# d -0.552270 0.533423 0.417096
# e -0.181280 -1.265713 0.474774
# f -0.701355 0.263040 -0.776085
使用df.iloc
df.iloc
的使用方式同上,只不过在进行列选时需要传入的列的位置而非索引
col_0and2 = df.iloc[:, [0, 2]]
# col_0and2的值为:
# A C
# a -1.622668 -0.161964
# b 0.784874 -0.117516
# c 0.696801 -1.544013
# d -0.552270 0.417096
# e -0.181280 0.474774
# f -0.701355 -0.776085
行选+列选
使用df.loc
使用df.loc
进行行选加列选时,需要指定行索引和列索引,具体使用方式为:df.loc[行选, 列选]
,行选和列选均可以使用切片操作:
或传入包含索引的列表
使用df.iloc
使用df.iloc进行行选加列选时,需要指定行位置和列位置,具体使用方式为:df.iloc[行位置, 列位置]
,行位置和列位置均可以使用切片操作:
或传入包含位置的列表
标量选择
df.loc
使用df.loc
进行标量选择时,行选和列选均需要是单个索引,即均不能使用:
和包含索引的列表,即使只有单个元素在列表中
df.iloc
使用df.iloc
进行标量选择时,行选和列选均需要是单个位置,即均不能使用:
和包含位置的列表,即使只有单个元素在列表中
df.at
使用df.at
进行标量选择时,需要提供行索引和列索引,该方法在行选和列选时只接受单个行索引和列索引,否则会出错
df.iat
使用df.iat
进行标量选择时,需要提供行位置和列位置,该方法在行选和列选时只接受单个行位置和列位置,否则会出错
总结
看完上面的内容,有没有发现,其实上述讲到的方法可以简单的分为以下几类,只不过索引的选择会决定获取到的结果
方法 | 概述 |
---|---|
使用 [pos/indexl] | 此方式不能同时进行行选加列选,当传入的是一个位置切片时,表示选择行,且选择行时必须传入一个切片,当传入的是索引时,表示选择列,此方式无法获取标量 |
使用 df.loc[row, col] | 此方式可以省略列选,如果省略,则表示所有列均被选中,行选和列选均需使用索引,当row和col的选择均为多个行和多个列时,返回的是一个DataFrame(行选和列选只要使用了 : 切片操作和列表,即使只有一个元素也会被视为多个行或列),当row和col的选择其中有一个为单个行或单个列时,返回的是一个Series,当row和col的选择均为单个行和单个列时,返回的是一个标量 |
使用 df.iloc[row, col] | 此方式可以省略列选,如果省略,则表示所有列均被选中,行选和列选均需使用位置,其它同df.loc[row, col] |
使用 df.at[row, col] | 此方式只用于获取标量,行选和列选必须同时指定,两者均只能选择单行和单列,且需为行索引和列索引,其它同df.loc |
使用 df.iat[row, col] | 此方式只用于获取标量,行选和列选必须同时指定,两者均只能选择单行和单列,且需为行位置和列位置,其它同df.loc |