标签与位置
这两种方法之间的主要区别在于:
-
loc
获取具有特定标签的行(和/或列)。 -
iloc
获取整数位置处的行(和/或列)。
为了演示,请考虑一系列具有非单调整数索引的字符:s
>>> s = pd.Series(list("abcdef"), index=[49, 48, 47, 0, 1, 2])
49 a
48 b
47 c
0 d
1 e
2 f
>>> s.loc[0] # value at index label 0
'd'
>>> s.iloc[0] # value at index location 0
'a'
>>> s.loc[0:1] # rows at index labels between 0 and 1 (inclusive)
0 d
1 e
>>> s.iloc[0:1] # rows at index location between 0 and 1 (exclusive)
49 a
以下是传递各种对象时和传递各种对象时的一些差异/相似之处:s.loc
s.iloc
<对象> | 描述 | s.loc[<object>] |
s.iloc[<object>] |
---|---|---|---|
0 |
单个项目 | 索引标签处的值(字符串0 'd' ) |
索引位置 0 处的值(字符串'a' ) |
0:1 |
片 |
两行(标签和0 1 ) |
一行(位置 0 处的第一行) |
1:47 |
具有越界结束的切片 | 零行(空系列) | 五行(位置 1 开始) |
1:47:-1 |
带负步长的切片 |
三行(标签返回1 47 ) |
零行(空系列) |
[2, 0] |
整数列表 | 具有给定标签的两行 | 具有给定位置的两行 |
s > 'e' |
布尔级数(指示哪些值具有该属性) |
一行(包含'f' ) |
NotImplementedError |
(s>'e').values |
布尔阵列 |
一行(包含'f' ) |
与 相同loc
|
999 |
int 对象不在索引中 | KeyError |
IndexError (超出范围) |
-1 |
int 对象不在索引中 | KeyError |
返回 中的最后一个值s
|
lambda x: x.index[3] |
可调用应用于系列(此处返回索引中的第 3 个项目) | s.loc[s.index[3]] |
s.iloc[s.index[3]] |
loc
的标签查询功能远远超出了整数索引的范围,值得强调几个其他示例。
下面是一个系列,其中索引包含字符串对象:
>>> s2 = pd.Series(s.index, index=s.values)
>>> s2
a 49
b 48
c 47
d 0
e 1
f 2
由于 是基于标签的,因此它可以使用 获取序列中的第一个值。它还可以使用非整数对象进行切片:loc
s2.loc['a']
>>> s2.loc['c':'e'] # all rows lying between 'c' and 'e' (inclusive)
c 47
d 0
e 1
对于 DateTime 索引,我们不需要传递按标签获取的确切日期/时间。例如:
>>> s3 = pd.Series(list('abcde'), pd.date_range('now', periods=5, freq='M'))
>>> s3
2021-01-31 16:41:31.879768 a
2021-02-28 16:41:31.879768 b
2021-03-31 16:41:31.879768 c
2021-04-30 16:41:31.879768 d
2021-05-31 16:41:31.879768 e
然后,要获取 2021 年 3 月/4 月的行,我们只需要:
>>> s3.loc['2021-03':'2021-04']
2021-03-31 17:04:30.742316 c
2021-04-30 17:04:30.742316 d
行和列
loc
并且使用数据帧的工作方式与使用序列的方式相同。请注意,这两种方法都可以同时处理列和行。iloc
给定元组时,第一个元素用于为行编制索引,如果存在,则第二个元素用于为列编制索引。
考虑下面定义的数据帧:
>>> import numpy as np
>>> df = pd.DataFrame(np.arange(25).reshape(5, 5),
index=list('abcde'),
columns=['x','y','z', 8, 9])
>>> df
x y z 8 9
a 0 1 2 3 4
b 5 6 7 8 9
c 10 11 12 13 14
d 15 16 17 18 19
e 20 21 22 23 24
然后例如:
>>> df.loc['c': , :'z'] # rows 'c' and onwards AND columns up to 'z'
x y z
c 10 11 12
d 15 16 17
e 20 21 22
>>> df.iloc[:, 3] # all rows, but only the column at index location 3
a 3
b 8
c 13
d 18
e 23
有时,我们希望混合使用行和列的标签和位置索引方法,以某种方式组合 和 的功能。loc
iloc
例如,请考虑以下数据帧。如何最好地将行切成“c”并包含“c”并取前四列?
>>> import numpy as np
>>> df = pd.DataFrame(np.arange(25).reshape(5, 5),
index=list('abcde'),
columns=['x','y','z', 8, 9])
>>> df
x y z 8 9
a 0 1 2 3 4
b 5 6 7 8 9
c 10 11 12 13 14
d 15 16 17 18 19
e 20 21 22 23 24
我们可以使用另一种方法和帮助来实现此结果:iloc
>>> df.iloc[:df.index.get_loc('c') + 1, :4]
x y z 8
a 0 1 2 3
b 5 6 7 8
c 10 11 12 13
get_loc()
是一个索引方法,意思是“获取标签在此索引中的位置”。请注意,由于 slicing with 不包含其端点,因此如果还需要行 'c',则必须在此值中添加 1。iloc
iloc
基于整数定位工作。因此,无论您的行标签是什么,您始终可以通过以下操作获得第一行
df.iloc[0]
或最后五行通过做
df.iloc[-5:]
您也可以在列上使用它。这将检索第 3 列:
df.iloc[:, 2] # the : in the first position indicates all rows
您可以将它们组合在一起以获得行和列的交集:
df.iloc[:3, :3] # The upper-left 3 X 3 entries (assuming df has 3+ rows and columns)
另一方面,使用命名索引。让我们设置一个数据框,其中包含字符串作为行标注和列标注:.loc
df = pd.DataFrame(index=['a', 'b', 'c'], columns=['time', 'date', 'name'])
然后我们可以通过以下方式获得第一行
df.loc['a'] # equivalent to df.iloc[0]
和列的后两行由'date'
df.loc['b':, 'date'] # equivalent to df.iloc[1:, 1]
等等。现在,可能值得指出的是,a 的默认行和列索引是从 0 开始的整数,在本例中,它们的工作方式相同。这就是为什么你的三个例子是等效的。如果您有非数字索引(如字符串或日期时间),则会引发错误。DataFrame
iloc
loc
df.loc[:5]
此外,您只需使用数据框的:__getitem__
df['time'] # equivalent to df.loc[:, 'time']
现在假设您要混合位置和命名索引,即使用行上的名称和列上的位置进行索引(为了澄清,我的意思是从我们的数据框中选择,而不是创建一个数据框,其中字符串在行索引中,整数在列索引中)。这就是进来的地方:.ix
df.ix[:2, 'time'] # the first two rows of the 'time' column
我认为还值得一提的是,您也可以将布尔向量传递给该方法。例如:loc
b = [True, False, True]
df.loc[b]
将返回 的第 1 行和第 3 行。这等效于用于选择,但它也可用于通过布尔向量进行赋值:df
df[b]
df.loc[b, 'name'] = 'Mary', 'John'