为什么 Pandas 中的 Pandas .loc 速度取决于 DataFrame 初始化?如何使 MultiIndex .loc 尽可能快?

2024-07-04

我正在尝试提高代码性能。 我使用 Pandas 0.19.2 和 Python 3.5。

我刚刚意识到,根据数据帧初始化的不同,一次写入一大堆值的 .loc 速度有很大不同。

有人可以解释为什么,并告诉我什么是最好的初始化吗?它可以让我加快我的代码速度。

这是一个玩具示例。我创建“相似”的数据框。

import pandas as pd
import numpy as np


ncols = 1000
nlines = 1000

columns = pd.MultiIndex.from_product([[0], [0], np.arange(ncols)])
lines = pd.MultiIndex.from_product([[0], [0], np.arange(nlines)])

#df has multiindex
df = pd.DataFrame(columns = columns, index = lines)

#df2 has mono-index, and is initialized a certain way
df2 = pd.DataFrame(columns = np.arange(ncols), index = np.arange(nlines))
for i in range(ncols):
    df2[i] = i*np.arange(nlines)

#df3 is mono-index and not initialized
df3 = pd.DataFrame(columns = np.arange(ncols), index = np.arange(nlines))

#df4 is mono-index and initialized another way compared to df2
df4 = pd.DataFrame(columns = np.arange(ncols), index = np.arange(nlines))
for i in range(ncols):
    df4[i] = i

然后我给他们计时:

%timeit df.loc[(0, 0, 0), (0, 0)] = 2*np.arange(ncols)
1 loop, best of 3: 786 ms per loop
The slowest run took 69.10 times longer than the fastest. This could mean          that an intermediate result is being cached.

%timeit df2.loc[0] = 2*np.arange(ncols)
1000 loops, best of 3: 275 µs per loop

%timeit df3.loc[0] = 2*np.arange(ncols)
10 loops, best of 3: 31.4 ms per loop

%timeit df4.loc[0] = 2*np.arange(ncols)
10 loops, best of 3: 63.9 ms per loop

我是不是做错了什么???为什么 df2 的性能比其他的快得多?实际上,在多索引情况下,使用 .at 逐一设置元素要快得多。我在代码中实现了这个解决方案,但我对此并不满意,我认为必须有更好的解决方案。我更愿意保留我漂亮的多索引数据框,但如果我真的需要使用单索引,我会这样做。

def mod(df, arr, ncols):
    for j in range(ncols):
        df.at[(0, 0, 0),(0, 0, j)] = arr[j]
    return df

%timeit mod(df, np.arange(ncols), ncols)
The slowest run took 10.44 times longer than the fastest. This could mean  that an intermediate result is being cached.
100 loops, best of 3: 14.6 ms per loop

我在这里看到的一个区别是,您(有效)使用 dtype=int64 初始化了 df2 和 df4,但使用 dtype=object 初始化了 df 和 df3。对于 df2 和 df4,您可以使用空实值进行初始化:

#df has multiindex
df = pd.DataFrame(np.empty([ncols,nlines]), 
                  columns = columns, index = lines)

#df3 is mono-index and not initialized
df3 = pd.DataFrame(np.empty([ncols,nlines]),
                   columns = np.arange(ncols), index = np.arange(nlines))

您还可以添加dtype=int初始化为整数而不是实数,但这似乎与速度无关。

我得到的时间比你对 df4 的时间快得多(代码没有区别),所以这对我来说是个谜。无论如何,通过上述对 df 和 df3 的更改,df2 到 df4 的时间很接近,但不幸的是 df 仍然很慢。

%timeit df.loc[(0, 0, 0), (0, 0)] = 2*np.arange(ncols)
1 loop, best of 3: 418 ms per loop

%timeit df2.loc[:,0] = 2*np.arange(ncols)
10000 loops, best of 3: 185 µs per loop

%timeit df3.loc[0] = 2*np.arange(ncols)
10000 loops, best of 3: 116 µs per loop

%timeit df4.loc[:,0] = 2*np.arange(ncols)
10000 loops, best of 3: 196 µs per loop

编辑添加:

至于多索引的更大问题,我不知道,但有两个想法:

1)扩展@ptrj的评论,我很快就得到了他的建议(与简单索引方法大致相同):

%timeit df.loc[(0, 0, 0) ] = 2*np.arange(ncols)
10000 loops, best of 3: 133 µs per loop

所以我再次得到了与你截然不同的时间(?)。 FWIW,当您想要整行带有 loc/iloc 时,建议使用:而不是将列引用留空:

timeit df.loc[(0, 0, 0), : ] = 2*np.arange(ncols)
1000 loops, best of 3: 223 µs per loop

但正如你所看到的,它有点慢,所以我不知道这里建议哪种方式。我想您通常应该按照文档的建议进行操作,但另一方面,这对您来说可能是速度上的重要差异。

2)或者,这相当暴力,但您可以保存索引/列,将索引/列重置为简单,然后将索引/列设置回多。虽然,这与仅仅采取没有什么不同df.values我怀疑对你来说不太方便。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 Pandas 中的 Pandas .loc 速度取决于 DataFrame 初始化?如何使 MultiIndex .loc 尽可能快? 的相关文章

随机推荐

  • HTTP 缓存标头设置 weblogic

    有谁知道如何修改 weblogic 设置以将 HTTP 缓存标头设置为遥远的未来日期 例如 在我当前的设置中 weblogic 将 http 缓存标头设置为在 5 小时后过期 作为 HTTP 1 1 304 Not Modified 的响应
  • .gitattributes 文件对于 git 真的有必要吗?

    我最近读了一些关于 gitattributes 的文章 也发现了像这样的地方 https github com alexkaratarakis gitattributes https github com alexkaratarakis g
  • 无法运行 com.android.ide.eclipse.adt.internal.build.AidlProcessor

    我从一位开发人员那里得到了一个项目 该项目已经完成并且在他的计算机上运行良好 当我尝试在 Eclipse 中在我的计算机上构建该项目时 我收到以下错误消息 无法运行 com android ide eclipse adt internal
  • Matplotlib 图例帮助

    我正在写一个脚本 其中包含几个要点 我也试图从这些点上创造一个传奇 总结我的脚本 我正在绘制几种 类型 的点 称为 a b c 这些点具有不同的颜色和形状 a go b rh c k 这是我的脚本相关部分的缩短版本 lbl the type
  • 如何查询我的 Subversion 存储库?

    目前 我只想找到过去 X 天内未修改的所有文件 但最终我希望能够对我的 subversion 存储库进行更复杂的查询 是否有我可以使用的某种 Subversion 查询语言或 API 您可以使用 SvnQuery 项目 http svnqu
  • Kotlin:在构造函数中初始化类属性

    我创建了一个带有类属性的 Kotlin 类 我想在构造函数中对其进行初始化 public class TestClass private var context Context null Nullable attribute public
  • 如何使用大量脚本文件管理 AngularJS 工作流程

    我研究了 gruntjs 但我不确定它是否是解决我的工作流程问题的正确工具 我正在开发一个巨大的 Angular 项目 其中已经有 30 多个 js 文件 每次添加新的 js 文件时 我都必须转到索引文件并在其中添加引用 有没有办法用 gr
  • 如何通过鼠标点击使一个对象移动并与另一个对象交换位置

    到目前为止 我有一个脚本 可以在单击鼠标时将对象移动一小段距离 但是我想更改它 以便当我单击该对象时 它会与旁边的另一个对象交换位置 而不仅仅是它所在的小距离现在搬家了 我对如何做到这一点有点困惑 因为我对统一很陌生 using Unity
  • 使用 ETag 进行 Volley 缓存

    我正在使用 Volley 库 但无法正确设置缓存 服务器向我发送 json 对象 过期时间和 ETag 我想将此对象保存在缓存中 并在下一个对该对象的请求中使用向服务器发送的请求 在标头中包含 ETag 如果响应为 304 Not Modi
  • 使用 Sublime Text 和正则表达式匹配行上的第一个空格

    所以正则表达式对我来说一直很困难 我试图找到一个正则表达式来选择一行上的第一个空格 这让我感到沮丧 那么我可以使用 sublime text 将其替换为 如果你能给出一个快速的解释 这将有助于 本着 edi 回答的精神 但对正在发生的事情进
  • 在挑选多个补丁时如何跳过一个补丁?

    我已经开始使用如下命令进行挑选 git cherry pick A B C D 假设补丁 A 和 B 有一些合并冲突 但我最终将它们全部修复并且git cherry pick continue 当我最终到达 C 时 我意识到一定已经应用了相
  • scala.tools.nsc.Interpreter -- 如何执行解释器语句以便在全局范围内定义结果? (Scala 2.7.7final)

    我正在尝试在 Scala 中解释字符串来定义类和方法 我使用了来自的例子http scala programming language 1934581 n4 nabble com Compiling a Scala Snippet at r
  • 每个 Service Fabric 实例的配置

    我正在设计一个服务结构无状态服务 它需要每个实例的配置数据 我最初的想法是创建命名分区 并使用PartitionInfo获取命名键 使用共享只读字典来加载每个实例的设置 问题是 现在在内部 从其他服务 访问此实例需要分区键 由于使用此方法的
  • 使用 junit 进行 Drools 测试

    使用 junit 测试 drools 规则的最佳实践是什么 到目前为止 我们使用 junit 和 dbunit 来测试规则 我们有放入 hsqldb 的示例数据 我们有几个规则包 到项目结束时 很难做出良好的测试输入来测试某些规则而不触发其
  • 我可以从图像文件的名称中获取图像文件的 Uri 吗?

    有一些图像文件 我想获取这些图像文件的Uri 在我的代码中 我只知道图像文件的路径和文件名 如何从路径和文件名中获取 Uri 如果你有一个File 您始终可以将其转换为URI File file new File path File pat
  • 如何获取所有行值制表符?

    我有使用制表器的可编辑表格 一切正常 但问题是单击 保存按钮 时无法获取所有行值 我正在尝试的是 document ready function var tabledata id 1 name Oli Bob age 12 col red
  • 将营业时间添加到 Java DateTime

    对于问题跟踪系统 我需要计算请求的响应时间 响应时间计时器只能在工作时间内运行 我应该使用什么算法 库来完成此任务 当然 我知道 Joda Time 或 ObjectLab Kit 但找不到任何对我的任务有帮助的东西 我错过了什么吗 Exa
  • 如何在 jest React Native 上调用或模拟 useForm?

    我有一个可重用的组件 称为 DatePicker 如下所示 export interface IPDatePicker extends IProps control any label string placeholder string v
  • git diff:--cached 和 --staged 之间有什么区别

    要将分阶段与上次提交进行比较 git diff cached git diff staged 两个命令生成相同的结果 对吧 的文档git diff says staged是 的同义词 cached 所以是的
  • 为什么 Pandas 中的 Pandas .loc 速度取决于 DataFrame 初始化?如何使 MultiIndex .loc 尽可能快?

    我正在尝试提高代码性能 我使用 Pandas 0 19 2 和 Python 3 5 我刚刚意识到 根据数据帧初始化的不同 一次写入一大堆值的 loc 速度有很大不同 有人可以解释为什么 并告诉我什么是最好的初始化吗 它可以让我加快我的代码