【问题标题】:Using .loc in pandas slows down calculation在 pandas 中使用 .loc 会减慢计算速度
【发布时间】:2018-02-16 12:55:22
【问题描述】:

我有以下数据框,我想将底部 1% 的值分配给新列。当我使用“.loc”通知进行此计算时,使用 .loc 分配大约需要 10 秒,而替代解决方案只需 2 秒。

df_temp = pd.DataFrame(np.random.randn(100000000,1),columns=list('A'))
%time df_temp["q"] = df_temp["A"].quantile(0.01)
%time df_temp.loc[:, "q1_loc"] = df_temp["A"].quantile(0.01)

为什么 .loc 解决方案较慢?我知道使用 .loc 解决方案更安全,但如果我想将数据分配给列中的所有索引,直接分配会出现什么问题?

【问题讨论】:

  • 我没有得到这样的差异In [355]: %time df_temp["q"] = df_temp["A"].quantile(0.01) Wall time: 1.67 s,In [356]: %time df_temp.loc[:, "q1_loc"] = df_temp["A"].quantile(0.01) Wall time: 1.92 s,In [357]: %time df.assign(q=df_temp["A"].quantile(0.01)) Wall time: 1.28 s,在pandas 0.22.0, python: 3.5.1., win 7中测试
  • 使用pandas 0.21.1,python 3.6.3,macOS 10.13.3,我得到了与 OP 相似的差异
  • 我正在使用 python 2.7.13 和 pandas 0.22.0。 sacul 提供的解决方案大约需要 5 秒。奇怪的是,如果我在不重新加载数据帧的情况下重新运行代码,第一个和第二个解决方案的计算时间几乎相等。 (2.53 vs 2.58 秒),assign 方法是最慢的,4.9 秒

标签: python pandas


【解决方案1】:

.loc 正在沿着整个轴在 df 中搜索整个索引和列(在这种情况下,只有 1 列),除了找出 @987654324 的分位数之外,这既费时又可能是多余的@(就计算时间而言可以忽略不计)。另一方面,您的直接分配方法只是解析df_temp['A'].quantile(0.01),然后分配df_temp['q']。它不需要详尽搜索您的 df 的索引/列。

有关.loc 方法的类似描述,请参阅this answer。

就安全而言,您没有使用链式索引,因此您可能是安全的(您没有尝试在数据的副本上设置任何内容,而是直接设置数据本身)。意识到不使用 .loc 的潜在问题是件好事(请参阅 this post 以获得对 SettingWithCopy 警告的一个很好的概述),但我认为就这一点而言你没问题。

如果您想更明确地说明您的列创建,您可以按照df = df.assign(q=df_temp["A"].quantile(0.01)) 的方式进行操作。它不会真正改变性能(我不认为),也不会改变结果,但它可以让您看到您正在为现有数据框明确分配一个新列(因此不会在所述数据框的副本上设置任何内容)。

【讨论】:

  • 谢谢。不幸的是,分配解决方案所需的时间仍然是直接分配的两倍多。我想我会坚持直接分配,尽管得到我应该 .loc 代替的警告有点烦人。
猜你喜欢
  • 2017-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-20
  • 2018-03-11
  • 2021-06-22
  • 1970-01-01
相关资源
最近更新 更多