Jam*_* Ko 11 python slice dataframe pandas
由于某些原因,以下两个调用iloc
/会loc
产生不同的行为:
>>> import pandas as pd
>>> df = pd.DataFrame(dict(A=range(3), B=range(3)))
>>> df.iloc[:1]
A B
0 0 0
>>> df.loc[:1]
A B
0 0 0
1 1 1
Run Code Online (Sandbox Code Playgroud)
我了解这会loc
考虑行标签,而会iloc
考虑行的基于整数的索引。但是为什么loc
呼叫的iloc
上限被认为是包含的,而上限却被认为是排他的呢?
快速回答:
使用标签时,进行端到端切片通常更有意义,因为它需要较少的有关DataFrame中其他行的知识。
每当您关心标签而不是位置时,末端排他的标签切片都会以一种不方便的方式引入位置依赖性。
更长的答案:
任何功能的行为都是一个权衡:您偏爱某些用例。最终,.iloc
Pandas开发人员的操作是主观的设计决定(如@ALlollz的评论所示,此行为是故意的)。但是要了解为什么他们可能会这样设计,请考虑一下使标签切片与位置切片不同的原因。
想象一下,我们有两个DataFrames df1
和df2
:
df1 = pd.DataFrame(dict(X=range(4)), index=['a','b','c','d'])
df1 = pd.DataFrame(dict(X=range(4)), index=['b','c','z'])
Run Code Online (Sandbox Code Playgroud)
df1
包含:
X
Y
a 0
b 1
c 2
d 3
Run Code Online (Sandbox Code Playgroud)
df2
包含:
X
Y
b 0
c 1
z 2
Run Code Online (Sandbox Code Playgroud)
比方说,我们有一个基于标签的任务来执行:我们希望之间获得行b
和c
来自df1
和df2
,我们希望使用相同的代码两个DataFrames做到这一点。因为b
和c
在两个DataFrame中都没有相同的位置,所以简单的位置切片无法解决问题。因此,我们转向基于标签的切片。
如果.loc
是end-exclusive,则要在它们之间获得行b
,c
我们不仅需要知道所需结束行的标签,还需要知道该行之后的下一行的标签。按照构造,下一个标签在每个DataFrame中将有所不同。
在这种情况下,我们将有两个选择:
df1.loc['b':'d']
和df2.loc['b':'z']
。这很不方便,因为这意味着我们需要了解除所需行之外的其他信息。df.loc[df.index.get_loc('b'):df.index.get_loc('c')+1]
。这只是罗word。但是由于.loc
包罗万象,所以我们只能说.loc['b':'c']
。简单得多!
每当您关心标签而不是位置,并且尝试编写与位置无关的代码时,包含结尾的标签切片都会以一种不方便的方式重新引入位置相关性。
就是说,也许在某些用例中,您确实希望基于标签的端排它切片。如果是这样,您可以在此问题中使用@Willz的答案:
df.loc[start:end].iloc[:-1]
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1374 次 |
最近记录: |