为什么我们对熊猫数据框使用“ loc”?似乎以下代码无论是否使用loc都以模拟速度运行
%timeit df_user1 = df.loc[df.user_id=='5561'] 100 loops, best of 3: 11.9 ms per loop
要么
%timeit df_user1_noloc = df[df.user_id=='5561'] 100 loops, best of 3: 12 ms per loop
那为什么要使用loc?
编辑:这已被标记为重复问题。但是,尽管熊猫iloc vs ix vs loc的解释?确实提到*
您可以只使用数据框的getitem进行列检索 :
*
df['time'] # equivalent to df.loc[:, 'time']
尽管它确实解释了loc的许多功能,但它并没有说明我们为什么使用loc,但我的特定问题是“为什么不完全省略loc”?为此,我在下面接受了非常详细的答案。
另外,其他帖子的答案(我认为不是答案)在讨论中非常隐蔽,任何搜索我正在寻找的人都将很难找到信息,并且提供的答案会更好地为您服务我的问题。
显式胜于隐式。
df[boolean_mask]选择行为boolean_maskTrue的行,但是在某些情况下可能不希望出现以下情况:当df具有布尔值的列标签时:
In [229]: df = pd.DataFrame({True:[1,2,3],False:[3,4,5]}); df Out[229]: False True 0 3 1 1 4 2 2 5 3
您可能要使用df[[True]]选择True列。相反,它引发一个ValueError:
In [230]: df[[True]] ValueError: Item wrong length 1 instead of 3.
与使用loc:
In [231]: df.loc[[True]] Out[231]: False True 0 3 1
相反,ValueError即使的结构df2几乎与df1上述相同,也不会出现以下情况:
In [258]: df2 = pd.DataFrame({'A':[1,2,3],'B':[3,4,5]}); df2 Out[258]: A B 0 1 3 1 2 4 2 3 5 In [259]: df2[['B']] Out[259]: B 0 3 1 4 2 5
因此,df[boolean_mask]并不总是与相同df.loc[boolean_mask]。即使这可以说是不太可能的用例,但我还是建议您始终使用df.loc[boolean_mask]而不是,df[boolean_mask]因为df.loc的语法含义很明确。随着df.loc[indexer]您自动知道,df.loc被选择行。相反,不清楚是否df[indexer]会ValueError在不了解indexer和的细节的情况下选择行或列(或引发)df。
df.loc[row_indexer, column_index]可以选择行和列。df[indexer]只能根据中的值类型和列值的类型选择行或列(再次,它们是布尔值吗?)。indexerdf
In [237]: df2.loc[[True,False,True], 'B'] Out[237]: 0 3 2 5 Name: B, dtype: int64
将切片传递给df.loc端点时,端点将包含在范围内。将切片传递给时df[…],该切片将被解释为半开间隔:
In [239]: df2.loc[1:2] Out[239]: A B 1 2 4 2 3 5 In [271]: df2[1:2] Out[271]: A B 1 2 4