pandas loc vs. iloc vs. ix vs. at vs. iat?

use*_*042 157 python lookup indexing performance pandas

最近开始从我的安全地点(R)扩展到Python,并且对于细胞定位/选择感到有些困惑Pandas.我已经阅读了文档,但我很难理解各种本地化/选择选项的实际意义.

  • 我有理由选择使用.loc.iloc超过最常用的选项.ix吗?
  • 我的理解是.loc,iloc,at,和iat可以提供一些保证正确性是.ix不能提供的,但我也看到了在那里.ix往往是一刀切最快的解决方案.
  • 请解释除了使用其他任何东西背后的现实世界,最佳实践推理.ix

小智 127

loc:仅适用于索引
iloc:处理位置
ix:您可以从dataframe获取数据,而不是在索引
处: get scalar values.这是一个非常快速的
locat:得到标量值.这是一个非常快的iloc

http://pyciencia.blogspot.com/2015/05/obtener-y-filtrar-datos-de-un-dataframe.html

注:由于pandas 0.20.0中,.ix索引被弃用赞成更加严格.iloc.loc索引.

  • `at`和`iat`a意味着访问标量,即数据帧中的单个元素,而`loc`和`iloc`可以同时访问多个元素,可能执行矢量化操作. (53认同)
  • 如果`at`和`iat`是`loc`和`iloc`的非常快的版本,那么为什么要使用`loc`和`iloc`? (7认同)
  • `.values[]` 比 `.iat` 更快 (2认同)

piR*_*red 89

针对不推荐使用的更新进行pandas 0.20了更新ix.这不但表明了如何使用loc,iloc,at,iat,set_value,但如何实现,混合位置/标签基于索引.


loc- 基于标签
允许您将1-D数组作为索引器传递.数组可以是索引或列的切片(子集),也可以是布尔数组,其长度与索引或列相等.

特别注意:当传递标量索引器时,loc可以分配之前不存在的新索引或列值.

# label based, but we can use position values
# to get the labels from the index object
df.loc[df.index[2], 'ColName'] = 3
Run Code Online (Sandbox Code Playgroud)
df.loc[df.index[1:3], 'ColName'] = 3
Run Code Online (Sandbox Code Playgroud)

iloc- 基于位置
类似于loc除了位置而不是索引值.但是,您无法分配新列或索引.

# position based, but we can get the position
# from the columns object via the `get_loc` method
df.iloc[2, df.columns.get_loc('ColName')] = 3
Run Code Online (Sandbox Code Playgroud)
df.iloc[2, 4] = 3
Run Code Online (Sandbox Code Playgroud)
df.iloc[:3, 2:4] = 3
Run Code Online (Sandbox Code Playgroud)

at- 基于标签的
作品与loc标量索引器非常相似. 无法对阵列索引器进行操作. 能够!分配新的索引和列.

优势loc是,这是速度更快.
缺点是您不能将数组用于索引器.

# label based, but we can use position values
# to get the labels from the index object
df.at[df.index[2], 'ColName'] = 3
Run Code Online (Sandbox Code Playgroud)
df.at['C', 'ColName'] = 3
Run Code Online (Sandbox Code Playgroud)

iat- 基于位置的
作品类似于iloc. 无法在数组索引器中工作. 不能!分配新的索引和列.

优势iloc是,这是速度更快.
缺点是您不能将数组用于索引器.

# position based, but we can get the position
# from the columns object via the `get_loc` method
IBM.iat[2, IBM.columns.get_loc('PNL')] = 3
Run Code Online (Sandbox Code Playgroud)

set_value- 基于标签的
作品与loc标量索引器非常相似. 无法对阵列索引器进行操作. 能够!分配新的索引和列

优势超快,因为开销很小!
缺点由于pandas没有进行大量安全检查,因此开销很小. 使用风险由您自己承担.此外,这不是供公众使用.

# label based, but we can use position values
# to get the labels from the index object
df.set_value(df.index[2], 'ColName', 3)
Run Code Online (Sandbox Code Playgroud)

set_valuetakable=True -基于位置的
作品类似于iloc. 无法在数组索引器中工作. 不能!分配新的索引和列.

优势超快,因为开销很小!
缺点由于pandas没有进行大量安全检查,因此开销很小. 使用风险由您自己承担.此外,这不是供公众使用.

# position based, but we can get the position
# from the columns object via the `get_loc` method
df.set_value(2, df.columns.get_loc('ColName'), 3, takable=True)
Run Code Online (Sandbox Code Playgroud)

  • 请注意,自版本 0.21 以来,`set_value` 已被弃用,取而代之的是 `.at` 和 `.iat` (4认同)

Ted*_*rou 54

pandas有两种主要方式可以从DataFrame中进行选择.

  • 标签
  • 整数位置

该文档使用术语位置来引用整数位置.我不喜欢这个术语,因为我觉得它很混乱.整数位置更具描述性,正是所.iloc代表的.这里的关键词是INTEGER - 在按整数位置选择时必须使用整数.

在显示摘要之前,让我们确保...

.ix已弃用且含糊不清,绝不应使用

大熊猫有三个主要的索引器.我们有索引操作符本身(括号[]).loc,和.iloc.让我们总结一下:

  • [] - 主要选择列的子集,但也可以选择行.无法同时选择行和列.
  • .loc - 仅按标签选择行和列的子集
  • .iloc - 仅按整数位置选择行和列的子集

我几乎从不使用.at.iat因为他们没有添加额外的功能,只是性能提升很小.除非你有一个非常时间敏感的应用程序,否则我会阻止它们的使用.无论如何,我们有他们的总结:

  • .at 仅按标签选择DataFrame中的单个标量值
  • .iat 仅按整数位置选择DataFrame中的单个标量值

除了按标签和整数位置选择之外,还存在布尔选择,也称为布尔索引.


示例解释.loc,.iloc布尔选择和.at.iat如下所示

我们将首先关注.loc和之间的差异.iloc.在我们讨论差异之前,重要的是要了解DataFrames具有帮助识别每列和每行的标签.我们来看一个示例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'])
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

所有粗体字都是标签.标签,age,color,food,height,scorestate被用于.其他标签,Jane,Nick,Aaron,Penelope,Dean,Christina,Cornelia用作标签的行.这些行标签统称为索引.


在DataFrame中选择特定行的主要方法是使用.loc.iloc索引器.这些索引器中的每一个也可用于同时选择列,但现在更容易关注行.此外,每个索引器都使用一组括号,这些括号紧跟其名称后进行选择.

.loc仅按标签选择数据

我们将首先讨论.loc仅通过索引或列标签选择数据的索引器.在我们的示例DataFrame中,我们提供了有意义的名称作为索引的值.许多DataFrames没有任何有意义的名称,而是默认只有从0到n-1的整数,其中n是DataFrame的长度.

您可以使用三种不同的输入 .loc

  • 一个字符串
  • 字符串列表
  • 使用字符串作为开始和停止值的切片表示法

使用带字符串的.loc选择单行

要选择单行数据,请将索引标签放在以下括号内.loc.

df.loc['Penelope']
Run Code Online (Sandbox Code Playgroud)

这会将数据行作为Series返回

age           4
color     white
food      Apple
height       80
score       3.3
state        AL
Name: Penelope, dtype: object
Run Code Online (Sandbox Code Playgroud)

使用带有字符串列表的.loc选择多行

df.loc[['Cornelia', 'Jane', 'Dean']]
Run Code Online (Sandbox Code Playgroud)

这将返回一个DataFrame,其中的行按列表中指定的顺序排列:

在此输入图像描述

使用切片表示法选择带有.loc的多行

切片表示法由开始,停止和步骤值定义.按标签切片时,pandas在返回时包含停止值.以下切片从Aaron到Dean,包括在内.其步长未明确定义,但默认为1.

df.loc['Aaron':'Dean']
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

复杂切片可以采用与Python列表相同的方式.

.iloc仅按整数位置选择数据

我们现在转向.iloc.DataFrame中的每一行和每列数据都有一个定义它的整数位置.这是在输出中以可视方式显示的标签的补充.整数位置只是从0开始的顶部/左侧的行数/列数.

您可以使用三种不同的输入 .iloc

  • 一个整数
  • 整数列表
  • 使用整数作为开始和停止值的切片表示法

使用带整数的.iloc选择单行

df.iloc[4]
Run Code Online (Sandbox Code Playgroud)

这将返回第5行(整数位置4)作为系列

age           32
color       gray
food      Cheese
height       180
score        1.8
state         AK
Name: Dean, dtype: object
Run Code Online (Sandbox Code Playgroud)

使用带有整数列表的.iloc选择多行

df.iloc[[2, -2]]
Run Code Online (Sandbox Code Playgroud)

这将返回第三行和第二行到最后一行的DataFrame:

在此输入图像描述

使用切片表示法选择带有.iloc的多行

df.iloc[:5:3]
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


使用.loc和.iloc同时选择行和列

两者的一个优秀能力.loc/.iloc是它们能够同时选择行和列.在上面的示例中,从每个选择中返回所有列.我们可以选择具有与行相同类型输入的列.我们只需要用逗号分隔行和列选择.

例如,我们可以选择行Jane,而Dean只选择列高度,分数和状态,如下所示:

df.loc[['Jane', 'Dean'], 'height':]
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

这使用行的标签列表和列的切片表示法

我们可以自然地.iloc只使用整数来执行类似的操作.

df.iloc[[1,4], 2]
Nick      Lamb
Dean    Cheese
Name: food, dtype: object
Run Code Online (Sandbox Code Playgroud)

使用标签和整数位置同时选择

.ix用于与标签和整数位置同时进行选择,这有时令人困惑和含糊不清,谢天谢地它已被弃用.如果您需要使用混合标签和整数位置进行选择,则必须同时选择标签或整数位置.

例如,如果我们想要选择行Nick以及第Cornelia2列和第4列,我们可以.loc通过将整数转换为带有以下内容的标签来使用:

col_names = df.columns[[2, 4]]
df.loc[['Nick', 'Cornelia'], col_names] 
Run Code Online (Sandbox Code Playgroud)

或者,使用get_loc索引方法将索引标签转换为整数.

labels = ['Nick', 'Cornelia']
index_ints = [df.index.get_loc(label) for label in labels]
df.iloc[index_ints, [2, 4]]
Run Code Online (Sandbox Code Playgroud)

布尔选择

.loc索引器也可以进行布尔选择.例如,如果我们有兴趣找到年龄超过30的所有行并返回foodscore列,我们可以执行以下操作:

df.loc[df['age'] > 30, ['food', 'score']] 
Run Code Online (Sandbox Code Playgroud)

您可以复制它,.iloc但不能将它传递给布尔系列.您必须将布尔系列转换为numpy数组,如下所示:

df.iloc[(df['age'] > 30).values, [2, 4]] 
Run Code Online (Sandbox Code Playgroud)

选择所有行

可以.loc/.iloc仅用于列选择.您可以使用冒号选择所有行,如下所示:

df.loc[:, 'color':'score':2]
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


索引操作符[]可以切片,也可以选择行和列,但不能同时选择.

大多数人都熟悉DataFrame索引操作符的主要用途,即选择列.字符串选择单个列作为Series,字符串列表选择多个列作为DataFrame.

df['food']

Jane          Steak
Nick           Lamb
Aaron         Mango
Penelope      Apple
Dean         Cheese
Christina     Melon
Cornelia      Beans
Name: food, dtype: object
Run Code Online (Sandbox Code Playgroud)

使用列表选择多个列

df[['food', 'score']]
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

人们不太熟悉的是,当使用切片表示法时,则通过行标签或整数位置进行选择.这非常混乱,我几乎从不使用它,但它确实有效.

df['Penelope':'Christina'] # slice rows by label
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

df[2:6:2] # slice rows by integer location
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

.loc/.iloc选择行的明确性是非常优选的.单独的索引操作符无法同时选择行和列.

df[3:5, 'color']
TypeError: unhashable type: 'slice'
Run Code Online (Sandbox Code Playgroud)

选择.at.iat

选择与.at几乎完全相同,.loc但它只在DataFrame中选择一个"单元格".我们通常将此单元格称为标量值.要使用.at,请将逗号分隔的行和列标签传递给它.

df.at['Christina', 'color']
'black'
Run Code Online (Sandbox Code Playgroud)

选择与.iat几乎相同,.iloc但它只选择一个标量值.您必须为行和列位置传递一个整数

df.iat[2, 5]
'FL'
Run Code Online (Sandbox Code Playgroud)


Lyd*_*dia 31

df = pd.DataFrame({'A':['a', 'b', 'c'], 'B':[54, 67, 89]}, index=[100, 200, 300])

df

                        A   B
                100     a   54
                200     b   67
                300     c   89
In [19]:    
df.loc[100]

Out[19]:
A     a
B    54
Name: 100, dtype: object

In [20]:    
df.iloc[0]

Out[20]:
A     a
B    54
Name: 100, dtype: object

In [24]:    
df2 = df.set_index([df.index,'A'])
df2

Out[24]:
        B
    A   
100 a   54
200 b   67
300 c   89

In [25]:    
df2.ix[100, 'a']

Out[25]:    
B    54
Name: (100, a), dtype: int64
Run Code Online (Sandbox Code Playgroud)