python - 通过不引用引用其他变量的变量等来优化python代码
问题描述
当我引用一个变量然后引用一个变量等等时,我有一个优化问题,每次我提到保存前一个变量的最后一个变量时,所有代码都会再次执行吗?
例如我的代码:
a = 5
b = 6
c = b * 2
d = a + c
e = c + d
f = e + d + c
g = f
h = g
现在在我的代码中,我说print(h)
,是否必须再次计算所有内容,或者当我引用它们时,python 会将所有值保存在内存中?当我在 python 中使用 SQL 和 pandas 时,我遇到了这个问题,当我连接到数据库时,获取我需要的内容,转换数据,然后将其加载到数据框,从原始数据框创建 3 个新数据框,然后提到具有1,000,000
行和50
列的 3 个数据帧之一,python 是否将所有这些百万记录保存在内存中?
感谢您的建议,我认为某处有一篇很好的文章解释了这一点,但我还没有完全找到我想要的东西。
解决方案
好吧,您应该提出一个精简版本的问题来构建一个最小的示例。在这里,您的代码几乎是最小的,但不幸的是与所描述的问题无关。
当涉及到内存时,重要的是对象而不是变量。在 Python 中,变量不再是引用底层对象的名称。只是一个对象结束了它的生命周期,并且一旦它不再可访问,就可以被垃圾收集以释放内存,这意味着一旦没有变量可以直接或间接地访问它。
例子:
a = "foo and bar" # ok a addresses the string
b = a # b addresses the same string (one single copy)
a += "s" # oops...
字符串是非可变类型。最后一行然后创建一个新字符串(用 寻址a
),同时b
仍然寻址旧字符串。之后b = None
,旧字符串将不再可访问,并将被垃圾收集。
a = [1, 2, 3, 4] # ok a point to the list
b = a # b addresses the same list
a.append(5) # oops...
列表是一种可变类型。a.append(5)
更改对象和两者a
,b
现在寻址列表 [1, 2, 3, 4, 5]。只是print(a,b)
用来看看...
现在对于您的确切问题:
pandas 底层容器是驻留在内存中的 numpy 数组。如果在某一时刻,您可以访问 3 个不同的数据帧,那么它们将存在于内存中。但是... pandas 是高度优化的。这意味着,如果您使用子数据帧,并且根据血腥细节,您将获得一个可以独立于原始数据帧进行更改的普通副本(内存中的重复),或者一个视图(使用相同的内存)。
让我们看一些 pandas 的例子:
Saydf
是一个只有数字数据的 1,000,000 行数据框。所有这些行都加载到内存中。
后:
for i in range(2, 11):
dg = df * i
... # process dg
对于每个步骤,您都会构建数据框的新副本,但它将在下一步被销毁。长话短说,您将使用两倍的初始数据帧内存
dfs = [df * i for i in range(2, 11)]
for dg in dfs:
... # process dg
在这里,您构建了 9 个可通过 dfs 访问的新数据帧,因此您以 10 个不同的数据帧结束,并且需要 10 倍的初始内存。
推荐阅读
- azure-pipelines - 如何在 Azure 管道中报告自定义检查样式报告
- python - 如何编写避免任何网络请求的 mitmproxy 插件?
- python - stringvar 如何与 textvariable 一起工作?
- sql - 确保 Postgresql 中没有两行包含相同的值
- database - 5NF 如何与具有 ID 列的原始表一起使用
- c - 如何设置结构数组的“结束”
- node.js - Mongoose.js 唯一验证
- python - 为什么python返回以下内容?
- typescript - 在 Typescript 中,`A` 可以分配给扩展 A 的`B`,如何处理?
- javascript - 如何使用输入标签将图像绘制到画布?