pandas 从 DataFrame 中进行选择有两种主要方式。
文档使用术语位置来指代整数位置。我不喜欢这个术语,因为我觉得它令人困惑。整数位置更具描述性,这正是.iloc 所代表的含义。这里的关键词是INTEGER——按整数位置选择时必须使用整数。
在显示摘要之前,让我们确保...
.ix 已弃用且模棱两可,永远不应使用
pandas 有三个主要的索引器。我们有索引运算符本身(方括号 [])、.loc 和 .iloc。让我们总结一下:
-
[] - 主要选择列的子集,但也可以选择行。不能同时选择行和列。
-
.loc - 仅按标签选择行和列的子集
-
.iloc - 仅按整数位置选择行和列的子集
我几乎从不使用 .at 或 .iat,因为它们没有添加任何额外的功能,而且性能提升很小。除非您的应用程序对时间非常敏感,否则我不鼓励使用它们。无论如何,我们有他们的总结:
-
.at 仅按标签在 DataFrame 中选择单个标量值
-
.iat 仅按整数位置选择 DataFrame 中的单个标量值
除了按标签和整数位置进行选择外,还存在布尔选择,也称为布尔索引。
解释.loc、.iloc、布尔选择和.at和.iat的示例如下所示
我们将首先关注.loc 和.iloc 之间的区别。在我们讨论差异之前,重要的是要了解 DataFrame 具有有助于识别每一列和每一行的标签。让我们看一个示例 DataFrame:
df = pd.DataFrame({'age':[30, 2, 12, 4, 32, 33, 69],
'color':['blue', 'green', 'red', 'white', 'gray', 'black', 'red'],
'food':['Steak', 'Lamb', 'Mango', 'Apple', 'Cheese', 'Melon', 'Beans'],
'height':[165, 70, 120, 80, 180, 172, 150],
'score':[4.6, 8.3, 9.0, 3.3, 1.8, 9.5, 2.2],
'state':['NY', 'TX', 'FL', 'AL', 'AK', 'TX', 'TX']
},
index=['Jane', 'Nick', 'Aaron', 'Penelope', 'Dean', 'Christina', 'Cornelia'])
粗体中的所有单词都是标签。标签age、color、food、height、score 和state 用于列。其他标签Jane、Nick、Aaron、Penelope、Dean、Christina、Cornelia 用作行的标签。这些行标签统称为索引。
在 DataFrame 中选择特定行的主要方法是使用 .loc 和 .iloc 索引器。这些索引器中的每一个也可用于同时选择列,但现在更容易只关注行。此外,每个索引器都使用一组紧跟其名称的括号来进行选择。
.loc 仅通过标签选择数据
我们将首先讨论.loc 索引器,它仅通过索引或列标签选择数据。在我们的示例 DataFrame 中,我们提供了有意义的名称作为索引的值。许多 DataFrame 没有任何有意义的名称,而是默认为从 0 到 n-1 的整数,其中 n 是 DataFrame 的长度(行数)。
many different inputs 可以用于.loc,其中三个是
- 一个字符串
- 字符串列表
- 使用字符串作为开始和结束值的切片表示法
使用带有字符串的 .loc 选择单行
要选择单行数据,请将索引标签放在.loc 后面的括号内。
df.loc['Penelope']
这会将数据行作为一个系列返回
age 4
color white
food Apple
height 80
score 3.3
state AL
Name: Penelope, dtype: object
使用带有字符串列表的 .loc 选择多行
df.loc[['Cornelia', 'Jane', 'Dean']]
这会返回一个 DataFrame,其中的行按列表中指定的顺序排列:
使用带有切片符号的 .loc 选择多行
切片符号由开始、停止和步长值定义。当按标签切片时,pandas 在返回值中包含停止值。以下切片从 Aaron 到 Dean,包括在内。它的步长没有明确定义,但默认为 1。
df.loc['Aaron':'Dean']
可以采用与 Python 列表相同的方式获取复杂切片。
.iloc 仅按整数位置选择数据
现在让我们转向.iloc。 DataFrame 中的每一行和每一列数据都有一个整数位置来定义它。这是在输出中直观显示的标签的补充。整数位置只是从 0 开始的顶部/左侧的行/列数。
many different inputs 可以用于.iloc,其中三个是
- 整数
- 整数列表
- 使用整数作为起始值和终止值的切片表示法
使用带有整数的 .iloc 选择单行
df.iloc[4]
这会将第 5 行(整数位置 4)作为系列返回
age 32
color gray
food Cheese
height 180
score 1.8
state AK
Name: Dean, dtype: object
使用带有整数列表的 .iloc 选择多行
df.iloc[[2, -2]]
这将返回第三行和倒数第二行的 DataFrame:
使用带有切片表示法的 .iloc 选择多行
df.iloc[:5:3]
使用 .loc 和 .iloc 同时选择行和列
.loc/.iloc 的一个出色能力是它们能够同时选择行和列。在上面的示例中,所有列都是从每个选择中返回的。我们可以选择输入类型与行相同的列。我们只需要用逗号分隔行和列选择。
例如,我们可以选择 Jane 和 Dean 行,只使用列高、分数和状态,如下所示:
df.loc[['Jane', 'Dean'], 'height':]
这对行使用标签列表,对列使用切片表示法
我们自然可以只使用整数对.iloc 进行类似的操作。
df.iloc[[1,4], 2]
Nick Lamb
Dean Cheese
Name: food, dtype: object
同时选择标签和整数位置
.ix 用于与标签和整数位置同时进行选择,这很有用,但有时令人困惑和模棱两可,谢天谢地,它已被弃用。如果您需要混合使用标签和整数位置进行选择,则必须同时选择标签或整数位置。
例如,如果我们想选择行 Nick 和 Cornelia 以及第 2 和 4 列,我们可以通过将整数转换为标签来使用 .loc:
col_names = df.columns[[2, 4]]
df.loc[['Nick', 'Cornelia'], col_names]
或者,使用get_loc 索引方法将索引标签转换为整数。
labels = ['Nick', 'Cornelia']
index_ints = [df.index.get_loc(label) for label in labels]
df.iloc[index_ints, [2, 4]]
布尔选择
.loc 索引器也可以进行布尔选择。例如,如果我们有兴趣查找年龄大于 30 的所有行并仅返回 food 和 score 列,我们可以执行以下操作:
df.loc[df['age'] > 30, ['food', 'score']]
您可以使用.iloc 复制它,但不能将其传递给布尔系列。您必须将布尔系列转换为 numpy 数组,如下所示:
df.iloc[(df['age'] > 30).values, [2, 4]]
选择所有行
可以使用.loc/.iloc 仅用于列选择。您可以使用这样的冒号选择所有行:
df.loc[:, 'color':'score':2]
索引运算符[] 可以切片也可以选择行和列,但不能同时选择。
大多数人都熟悉 DataFrame 索引运算符的主要用途,即选择列。字符串选择单列作为 Series,字符串列表选择多列作为 DataFrame。
df['food']
Jane Steak
Nick Lamb
Aaron Mango
Penelope Apple
Dean Cheese
Christina Melon
Cornelia Beans
Name: food, dtype: object
使用列表选择多列
df[['food', 'score']]
人们不太熟悉的是,当使用切片表示法时,选择是通过行标签或整数位置进行的。这非常令人困惑,而且我几乎从未使用过,但它确实有效。
df['Penelope':'Christina'] # slice rows by label
df[2:6:2] # slice rows by integer location
.loc/.iloc 用于选择行的明确性是非常受欢迎的。单独的索引运算符无法同时选择行和列。
df[3:5, 'color']
TypeError: unhashable type: 'slice'
由.at 和.iat 选择
使用.at 进行选择几乎与.loc 相同,但它只选择DataFrame 中的一个“单元格”。我们通常将此单元格称为标量值。要使用.at,请将行标签和列标签都传递给它,并用逗号分隔。
df.at['Christina', 'color']
'black'
.iat 的选择与.iloc 几乎相同,但它只选择一个标量值。您必须为行和列位置传递一个整数
df.iat[2, 5]
'FL'