首页 > 解决方案 > 通过不引用引用其他变量的变量等来优化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 是否将所有这些百万记录保存在内存中?

感谢您的建议,我认为某处有一篇很好的文章解释了这一点,但我还没有完全找到我想要的东西。

标签: pythonoptimizationmemory-management

解决方案


好吧,您应该提出一个精简版本的问题来构建一个最小的示例。在这里,您的代码几乎是最小的,但不幸的是与所描述的问题无关。

当涉及到内存时,重要的是对象而不是变量。在 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)更改对象和两者ab现在寻址列表 [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 倍的初始内存。


推荐阅读