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

新手上路,请多包涵

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

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

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

第二种方法 - 似乎更简单,更快:

 df_new = df['col1']

第三种方法 - 最方便:

 df_new = df.col1

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

我很好奇为什么似乎有三种方法可以做同样的事情。

原文由 Sean McCarthy 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 699
2 个回答

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

  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 -398 而不是 iloc ,假设您有 RangeIndex ,您将获得第 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 的回答


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

原文由 ayhan 发布,翻译遵循 CC BY-SA 4.0 许可协议

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']

原文由 Freeman 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题