在以下代码中:
@profile
def do():
import random
import numpy as np
image = np.memmap('image.np', mode='w+', dtype=np.float32, shape=(10000, 10000))
print("Before assignment")
x = random.uniform(1000, 9000)
y = random.uniform(1000, 9000)
imin = int(x) - 128
imax = int(x) + 128
jmin = int(y) - 128
jmax = int(y) + 128
data = np.random.random((256,256))
image[imin:imax, jmin:jmax] = image[imin:imax, jmin:jmax] + data
del x, y, imin, imax, jmin, jmax, data
print("After assignment")
do()
与第一个print语句结束时相比,第二个print语句中使用的内存增加了 - 这是memory_profiler输出:
Line # Mem usage Increment Line Contents
================================================
1 @profile
2 def do():
3 10.207 MB 0.000 MB
4 10.734 MB 0.527 MB import random
5 21.066 MB 10.332 MB import numpy as np
6
7 21.105 MB 0.039 MB image = np.memmap('image.np', mode='w+', dtype=np.float32, shape=(10000, 10000))
8
9 21.109 MB 0.004 MB print("Before assignment")
10
11 21.109 MB 0.000 MB x = random.uniform(1000, 9000)
12 21.109 MB 0.000 MB y = random.uniform(1000, 9000)
13 21.109 MB 0.000 MB imin = int(x) - 128
14 21.109 MB 0.000 MB imax = int(x) + 128
15 21.113 MB 0.004 MB jmin = int(y) - 128
16 21.113 MB 0.000 MB jmax = int(y) + 128
17 21.625 MB 0.512 MB data = np.random.random((256,256))
18 23.574 MB 1.949 MB image[imin:imax, jmin:jmax] = image[imin:imax, jmin:jmax] + data
19
20 23.574 MB 0.000 MB del x, y, imin, imax, jmin, jmax, data
21
22 23.574 MB 0.000 MB print("After assigment")
RAM从21.109Mb增加到23.574Mb。如果我将该代码块放在循环中,这会导致问题:
Line # Mem usage Increment Line Contents
================================================
1 @profile
2 def do():
3 10.207 MB 0.000 MB
4 10.734 MB 0.527 MB import random
5 21.066 MB 10.332 MB import numpy as np
6
7 21.105 MB 0.039 MB image = np.memmap('image.np', mode='w+', dtype=np.float32, shape=(10000, 10000))
8
9 21.109 MB 0.004 MB print("Before assignment")
10
11 292.879 MB 271.770 MB for i in range(1000):
12
13 292.879 MB 0.000 MB x = random.uniform(1000, 9000)
14 292.879 MB 0.000 MB y = random.uniform(1000, 9000)
15 292.879 MB 0.000 MB imin = int(x) - 128
16 292.879 MB 0.000 MB imax = int(x) + 128
17 292.879 MB 0.000 MB jmin = int(y) - 128
18 292.879 MB 0.000 MB jmax = int(y) + 128
19 292.879 MB 0.000 MB data = np.random.random((256,256))
20 292.879 MB 0.000 MB image[imin:imax, jmin:jmax] = image[imin:imax, jmin:jmax] + data
21
22 292.879 MB 0.000 MB del x, y, imin, imax, jmin, jmax, data
23
24 292.879 MB 0.000 MB print("After assignment")
并且所使用的RAM将在每次迭代时增加。有没有办法避免这个问题?这是一个Numpy bug还是我做错了什么?
编辑:这是在MacOS X上,我看到Python 2.7和3.2的问题,Numpy 1.6.2及更高版本(包括开发版)。编辑2:我也在Linux上看到了这个问题。
答案 0 :(得分:1)
我的猜测是numpy首先将数据写入缓冲区,然后才将文件写入文件。可能出于性能原因。
我做了一些测试,在你的作业行之后,文件image.np
没有改变。删除对象image
或执行image.flush()
后,文件才会更改。如果内存是最重要的,您可以尝试在循环中放置image.flush()
以查看它是否解决了问题。
答案 1 :(得分:0)
出于优化原因,在调用np.memmap
的析构函数之前,可能无法从image
写入数据。您可以通过打开image
作为写时复制来避免这种情况:
image = np.memmap('image.np', mode='c', dtype=np.float32, shape=(10000, 10000))
或者你可以调用del image
然后在每个循环中重新打开一次 - 但这听起来不是一个好主意。