使用loc和仅使用方括号来过滤Pandas / Python中的列有什么区别?


77

我注意到在Pandas DataFrame中选择列的三种方法:

使用loc选择列的第一种方法:

df_new = df.loc[:, 'col1']

第二种方法-看起来更简单,更快:

df_new = df['col1']

第三种方法-最方便:

df_new = df.col1

这三种方法之间有区别吗?我不这么认为,在这种情况下,我宁愿使用第三种方法。

我最奇怪的是为什么似乎有三种方法可以做同一件事。


1
还是呢df.col1?对于选择列的非常简单的情况,所有这三个属性基本上都是等效的。.loc除了选择一列,您还可以做更多的事情。可能是stackoverflow.com/questions/31593201/…的
juanpa.arrivillaga,

1
对于简单的切片,它们执行相同的操作。loc更明确,尤其是当您的列是数字时。
加布里埃尔A

谢谢@ juanpa.arrivillaga。好要点:df.col1,这是选择列的另一种方法。实际上,我之前已经看过几次其他问题。这对于解释loc和iloc非常有用。但是,此问题与另一种方法有关:“ df ['col1']”。我只是对为什么有两种(或三种)等效的方法来做似乎是同一件事感到困惑。
肖恩·麦卡锡

1
第三种方法的最大缺点是,当您的列名与现有的pandas属性或方法相同时,它的模棱两可。例如,您将列命名为“ sum”。然后,如果您键入df.sum,会发生什么?(扰流板警报,没什么用,尽管df.sum()仍然可以幸运地起作用)所以第三种方法应该被视为是一种捷径,但是,请务必谨慎
-JohnE

1
这里的一个体面的解释stackoverflow.com/questions/38886080/...
拉夫塔尼亚

Answers:


79

在以下情况下,它们的行为相同:

  1. 选择单个列(df['A']df.loc[:, 'A']->选择列A相同)
  2. 选择列列表(df[['A', 'B', 'C']]df.loc[:, ['A', 'B', 'C']]->选择列A,B和C相同)
  3. 按行切片(df[1:3]df.iloc[1:3]->选择第1行和第2行相同。但是请注意,如果您使用loc而不是进行切片,则iloc假设您具有RandeIndex,则将获得第1、2和3行。请参见此处的详细信息。)

但是,[]在以下情况下不起作用:

  1. 您可以使用 df.loc[row_label]
  2. 您可以使用 df.loc[[row_label1, row_label2]]
  3. 您可以使用 df.loc[:, 'A':'C']

这三个不能用来完成[]。更重要的是,如果您的选择同时涉及到行和列,那么分配就会成问题。

df[1:3]['A'] = 5

这将选择行1和2,然后选择返回对象的列“ A”并为其分配值5。问题是,返回的对象可能是副本,因此这可能不会更改实际的DataFrame。这将引发 SettingWithCopyWarning。这种分配的正确方法是

df.loc[1:3, 'A'] = 5

使用.loc,可以确保修改原始DataFrame。它还允许您对列(df.loc[:, 'C':'F'])进行切片,选择单行(df.loc[5])和选择行列表(df.loc[[1, 2, 5]])。

另请注意,这两个未同时包含在API中。.loc后来被添加为更强大,更明确的索引器。有关更多详细信息,请参见unutbu的答案


注意:使用[]vs获取列.是一个完全不同的主题。.只是为了方便。它仅允许访问其名称为有效Python标识符的列(即它们不能包含空格,它们不能由数字组成...)。当名称与Series / DataFrame方法冲突时,不能使用它。它也不能用于不存在的列(即,df.a = 1如果没有column ,分配将不起作用a)。除此之外,.并且[]是相同的。


6

loc当索引不是数字(例如,DatetimeIndex)时,此功能特别有用,因为您可以从索引中获取带有特定标签的

df.loc['2010-05-04 07:00:00']
df.loc['2010-1-1 0:00:00':'2010-12-31 23:59:59 ','Price']

但是[]旨在获取具有特定名称的

df['Price']

随着[]您还可以过滤,但它更多的阐述:

df[df['Date'] < datetime.datetime(2010,1,1,7,0,0)]['Price']

0

创建具有多列的数据框时,df.loc []和df []之间似乎有所不同。

您可以参考以下问题: 是否有一种使用.loc生成多列的好方法?

在这里,您不能使用来生成多列,df.loc[:,['name1','name2']]而只需使用doublecket即可df[['name1','name2']]。(我想知道为什么他们的行为有所不同。)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.