8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

为什么在 Pandas 中使用 loc?

raymond van ophoven 1月前

38 0

为什么我们要对 pandas 数据框使用 loc?似乎以下代码(无论是否使用 loc)的编译和运行速度都差不多:%timeit df_user1 = df.loc[df.user_id=='5561']100 loops, b...

为什么我们要使用 loc pandas 数据框?似乎以下代码无论是否使用, 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

编辑: 这已被标记为重复问题。但尽管 pandas iloc vs ix vs loc 解释? 确实提到了这一点

您只需使用数据框即可进行列检索 __getitem__

df['time']    # equivalent to df.loc[:, 'time']

它没有说明为什么我们使用 loc ,尽管它确实解释了 的许多特性 loc 。但我的具体问题是:为什么不干脆 loc 完全省略?对于这个问题,我接受了下面的一个非常详细的答案。

另外,在上面的帖子中,答案(我不认为是一个答案)在讨论中隐藏得很好,任何搜索我所问问题的人都会发现很难找到信息,而这里为我的问题提供的答案会更有帮助。

帖子版权声明 1、本帖标题:为什么在 Pandas 中使用 loc?
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由raymond van ophoven在本站《pandas》版块原创发布, 转载请注明出处!
最新回复 (0)
    • p0

      p1

      In [229]: df = pd.DataFrame({True:[1,2,3],False:[3,4,5]}); dfOut[229]:    False  True 0      3      11      4      22      5      3

      p2

      In [230]: df[[True]]ValueError: Item wrong length 1 instead of 3.

      p3

      In [231]: df.loc[[True]]Out[231]:    False  True 0      3      1

      p4

      In [258]: df2 = pd.DataFrame({'A':[1,2,3],'B':[3,4,5]}); df2Out[258]:    A  B0  1  31  2  42  3  5In [259]: df2[['B']]Out[259]:    B0  31  42  5

      p5

    • p6

      In [237]: df2.loc[[True,False,True], 'B']Out[237]: 0    32    5Name: B, dtype: int64
    • p7

      In [239]: df2.loc[1:2]Out[239]:    A  B1  2  42  3  5In [271]: df2[1:2]Out[271]:    A  B1  2  4
  • 为什么不在列名周围使用引号? df[['True']] 不能正常工作吗?

  • @LS df[['True']] 在示例中似乎无法正常工作。列名不是字符串,而是布尔对象。看起来 pandas 不要求列名为字符串(不同于例如 R,其中 names(df) 是字符,而 [[]] 将输入强制为字符)

  • 切片的一个重要区别是 loc[1:2] 作用于索引,而 df2[1:2] 作用于行的简单顺序,与索引无关。在上面的最后一个例子中,如果索引以 [3,4] 开头,则 loc[1:2] 不会返回任何内容,而 df2[1:2] 仍将返回索引为 3 的第一行。

  • 另一件事是 loc 总是会进行复制,而非 loc 方法则不会:请参阅 .com/questions/20625582/… 因此,非 loc 方法导致在切片数据帧时必须明确添加 .copy() ,以处理 settingwithcopywarning

  • 使用和不使用 .loc 对多列“链式赋值”的性能考虑

    让我从系统性能的角度来补充一下已经非常好的答案。

    问题本身包括对使用和不使用 .loc 的两段代码的系统性能(执行时间)的比较。对于引用的代码示例,执行时间大致相同。但是,对于其他一些代码示例, 使用和不使用 .loc 的执行时间可能会有相当大的差异 :例如相差几倍甚至更多!

    操作 pandas dataframe 的一个常见情况是我们需要创建一个从现有列的值派生的新列。我们可以使用以下代码来过滤条件(基于现有列)并为新列设置不同的值:

    df[df['mark'] >= 50]['text_rating'] = 'Pass'
    

    但是,这种“链式分配”不起作用,因为它可以创建“副本”而不是“视图”,并且基于此“副本”对新列的分配不会更新原始数据框。

    有 2 个选项:

      1. 我们可以使用.loc,或者
      1. 不使用 .loc,以其他方式编码

    第二种情况例如:

    df['text_rating'][df['mark'] >= 50] = 'Pass'
    

    通过将过滤放在最后(指定新列名之后),分配可以很好地与更新的原始数据框配合使用。

    使用.loc的解决方案如下:

    df.loc[df['mark'] >= 50, 'text_rating'] = 'Pass'
    

    现在,让我们看看它们的执行时间:

    不使用 .loc

    %%timeit 
    df['text_rating'][df['mark'] >= 50] = 'Pass'
    
    2.01 ms ± 105 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
    

    使用 .loc

    %%timeit 
    df.loc[df['mark'] >= 50, 'text_rating'] = 'Pass'
    
    577 µs ± 5.13 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
    

    我们可以看到, 使用 .loc 后,执行时间提高了 3 倍以上!

    有关 \'Chained Assignment\' 的更详细解释,您可以参考另一篇相关文章 How to deal with SettingWithCopyWarning in pandas? ,特别是 cs95 的答案 。该帖子很好地解释了使用 .loc 的功能差异。我只是在这里补充系统性能(执行时间)差异。

  • 除了已经说过的内容(不使用 loc 时将 True、False 作为列名的问题,以及使用 loc 选择行和列的能力以及对行和列选择进行切片的能力),另一个很大的区别是您可以使用 loc 为特定的行和列分配值。如果您尝试使用布尔系列选择数据框的子集并尝试更改该子集选择的值,您可能会收到 SettingWithCopy 警告。

    假设您尝试更改所有工资大于 60,000 的行的“高层管理人员”列。

    这:

    mask = df["salary"] > 60000
    df[mask]["upper management"] = True
    

    抛出警告“正尝试在 Dataframe 切片的副本上设置一个值”,并且不起作用,因为 df[mask] 创建了一个副本,而尝试更新该副本的“上层管理”对原始 df 没有影响。

    但这成功了:

    mask = df["salary"] > 60000
    df.loc[mask,"upper management"] = True
    

    请注意,在两种情况下您都可以执行 df[df["salary"] > 60000] df.loc[df["salary"] > 60000] ,但我认为首先将布尔条件存储在变量中更清晰。

返回
作者最近主题: