提问人:Sean McCarthy 提问时间:1/24/2018 最后编辑:Mad PhysicistSean McCarthy 更新时间:11/12/2021 访问量:47155
在 Pandas/Python 中使用 loc 和仅使用方括号过滤列有什么区别?
What is the difference between using loc and using just square brackets to filter for columns in Pandas/Python?
问:
我注意到在 Pandas DataFrame 中选择列的三种方法:
使用 loc 选择列的第一种方法:
df_new = df.loc[:, 'col1']
第二种方法 - 似乎更简单、更快捷:
df_new = df['col1']
第三种方法 - 最方便:
df_new = df.col1
这三种方法之间有区别吗?我不这么认为,在这种情况下,我宁愿使用第三种方法。
我最好奇为什么似乎有三种方法可以做同样的事情。
答:
在以下情况下,它们的行为相同:
- 选择单个列(与 -> 选择 A 列相同)
df['A']
df.loc[:, 'A']
- 选择列列表(与 -> 选择列 A、B 和 C 相同)
df[['A', 'B', 'C']]
df.loc[:, ['A', 'B', 'C']]
- 按行切片 ( 与 -> 选择第 1 行和第 2 行相同。但是请注意,如果使用 ,而不是 ,则将获得第 1、2 和 3 行(假设您有 RangeIndex)。详情请见此处。
df[1:3]
df.iloc[1:3]
loc
iloc
但是,在以下情况下不起作用:[]
- 您可以选择单行
df.loc[row_label]
- 您可以选择具有
df.loc[[row_label1, row_label2]]
- 您可以使用以下命令对列进行切片
df.loc[:, 'A':'C']
这三个不能用 .
更重要的是,如果您的选择同时涉及行和列,则赋值将出现问题。[]
df[1:3]['A'] = 5
这将选择第 1 行和第 2 行,然后选择返回对象的列“A”,并为其分配值 5。问题是,返回的对象可能是一个副本,因此这可能不会更改实际的 DataFrame。这将引发 SettingWithCopyWarning。进行此分配的正确方法是:
df.loc[1:3, 'A'] = 5
使用 ,可以保证修改原始 DataFrame。它还允许您对列 ()、选择单行 () 和选择行列表 ()。.loc
df.loc[:, 'C':'F']
df.loc[5]
df.loc[[1, 2, 5]]
另请注意,这两个没有同时包含在 API 中。 很久以后才添加为更强大、更显式的索引器。有关更多详细信息,请参阅 unutbu 的回答。.loc
注意:获取带有 vs 的列是一个完全不同的主题。 只是为了方便。它只允许访问名称为有效 Python 标识符的列(即它们不能包含空格,不能由数字组成......当名称与 Series/DataFrame 方法冲突时,不能使用它。它也不能用于不存在的列(即,如果没有列,则赋值将不起作用)。除此之外,都是一样的。[]
.
.
df.a = 1
a
.
[]
评论
df[1:3]['A'] = 5
df.__getitem__(...)
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']
当您创建具有多个列的 DataFrame 时,df.loc[] 和 df[] 之间似乎存在差异。
您可以参考这个问题:有没有使用 .loc 生成多个列的好方法?
在这里,您不能使用生成多列,但可以仅使用双括号来生成多列。(我想知道为什么他们的行为不同。df.loc[:,['name1','name2']]
df[['name1','name2']]
评论
如果您对以下哪种方法(至少)是您的用例推荐的方法感到困惑,请查看 pandas 教程中的简要说明:
选择数据子集时,使用方括号。
[]
在这些括号内,您可以使用单个列/行标签,即列表 列/行标签、标签切片、条件表达式或 冒号。
选择特定的行和/或列,使用行和 列名
loc
选择特定的行和/或列,使用 表中的位置
iloc
您可以根据 / 为所选内容分配新值。
loc
iloc
我强调了一些要点,以使其用例差异更加清晰。
评论
df.col1
.loc
df.sum
df.sum()