从pandas DataFrame中选择时的内存优化

4 投票
2 回答
805 浏览
提问于 2025-04-18 16:30

我有一个比较大的 pandas 数据框(1.7G),我想从中选择一些列来进行计算(找出三列中的最大值)。这个操作似乎占用了很多内存。我在想有没有办法减少这种内存的消耗。

为了简化这个问题,我用假数据来演示我的数据框。下面是我的代码和内存使用情况,

from memory_profiler import profile
import pandas as pnd
import random


@profile
def main():
    cols = [chr(i) for i in range(65,91)]
    d = {}
    n = 1000000
    for c in cols:
        d[c] = [random.randint(0,100) for i in range(n)]
    df = pnd.DataFrame(d)
    items = ['A','F','G']
    a = df[items]
    b = a.max(axis=0)


if __name__ == "__main__":
    main()


Line #    Mem usage    Increment   Line Contents
================================================
     6     42.3 MiB      0.0 MiB   @profile
     7                             def main():
     8     42.3 MiB      0.0 MiB       cols = [chr(i) for i in range(65,91)]
     9     42.3 MiB      0.0 MiB       d = {}
    10     42.3 MiB      0.0 MiB       n = 1000000
    11    240.6 MiB    198.3 MiB       for c in cols:
    12    240.6 MiB      0.0 MiB           d[c] = [random.randint(0,100) for i in range(n)]
    13    446.7 MiB    206.1 MiB       df = pnd.DataFrame(d)
    14    446.7 MiB      0.0 MiB       items = ['A','F','G']
    15    469.7 MiB     23.1 MiB       a = df[items]
    16    469.8 MiB      0.1 MiB       b = a.max(axis=0)

在上面的操作中,似乎 df[items] 使用了 23MB 的内存。我猜测这是因为它在复制数据框,并把这个副本放在了 'a' 里。

有没有办法在选择列的时候减少这种内存的占用呢?

2 个回答

0

如果你只是做一些计算,其实不需要把列单独选出来放到新的变量里,也不需要创建副本。

你可以直接使用函数来计算——这样做可能会占用更多的CPU,因为它会计算所有的最大值,然后再选出你需要的,但这样就不需要创建新的变量了。

df.max()[['A','F','G']]

或者你可以快速遍历一下你需要计算最大值的列,简单地一次选择一列来尝试获取结果(因为你不能用复杂的切片来获取结果)。

1

Pandas在大多数操作中会返回数据的副本。某些选择操作可能会返回一个视图,也就是说,内存可能不会被复制,而是直接指向底层的numpy视图。一般来说,这个行为是由numpy来控制的。像你所做的那种操作(比如不连续的切片)永远不会返回视图。

不过,更重要的是,这其实并不影响结果,因为一旦对变量的引用被释放,内存就会被垃圾回收。

你在这里的目标是什么呢?

撰写回答