从pandas DataFrame中选择时的内存优化
我有一个比较大的 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来控制的。像你所做的那种操作(比如不连续的切片)永远不会返回视图。
不过,更重要的是,这其实并不影响结果,因为一旦对变量的引用被释放,内存就会被垃圾回收。
你在这里的目标是什么呢?