numpy memmap
什么是numpy中的memmap
在numpy中,memmap是一种特殊的数组类型,它允许将数组保存在磁盘上,而不是保存在内存中。这样可以节省内存空间,并且在处理大型数组时可以提高性能。
memmap数组实际上是在磁盘上存储的一个文件,但在使用时,它表现得就像一个普通的numpy数组一样。可以对memmap数组进行索引、切片、运算等操作,所有的操作都会在磁盘上进行,而不是在内存中进行。
如何创建memmap数组
在numpy中,可以使用numpy.memmap函数来创建一个memmap数组。这个函数的语法如下:
np.memmap(filename, dtype='float64', mode='r+', shape=(m, n))
- filename: 要保存memmap数组的文件路径
- dtype: 数组元素的数据类型,默认为float64
- mode: 文件打开模式,有’r’, ‘r+’, ‘w+’, ‘c’等选项
- shape: 数组的形状,以元组形式指定
下面是一个创建memmap数组的示例代码:
import numpy as np
# 创建一个500x500的memmap数组
filename = 'memmap_array.dat'
shape = (500, 500)
memmap_arr = np.memmap(filename, dtype='float64', mode='w+', shape=shape)
# 将数组的每个元素设置为1
memmap_arr[:] = 1
# 切片操作,在内存中查看该切片
memmap_slice = memmap_arr[:10, :10]
print(memmap_slice)
# 关闭memmap数组
del memmap_arr
运行以上代码,会创建一个500×500的memmap数组,将所有元素设置为1,并对数组进行切片操作。注意,在关闭memmap数组之前,一定要将其赋值给一个变量或者显示地删除,否则关闭文件时内存中可能会保存副本,消耗额外的内存空间。
memmap数组的操作
memmap数组支持和普通numpy数组相同的操作,比如索引、切片、运算等。但是需要注意的是,对memmap数组的操作会在磁盘上进行,因此会有一定的性能损耗。
索引和切片
可以对memmap数组进行索引和切片操作,获取指定位置的元素或者子数组。需要注意的是,对切片的修改会直接反映到磁盘上的数组中。
import numpy as np
# 打开一个已经存在的memmap数组
filename = 'memmap_array.dat'
shape = (500, 500)
memmap_arr = np.memmap(filename, dtype='float64', mode='r+', shape=shape)
# 获取第一行数据
first_row = memmap_arr[0]
print(first_row)
# 修改第二列数据
memmap_arr[:, 1] = 2
# 切片操作
memmap_slice = memmap_arr[:10, :10]
print(memmap_slice)
# 关闭memmap数组
del memmap_arr
运算
和普通的numpy数组一样,memmap数组也支持各种数学运算。这些运算会在磁盘上进行,因此,对于大型数组,运算可能会比较耗时。
import numpy as np
# 打开一个已经存在的memmap数组
filename = 'memmap_array.dat'
shape = (500, 500)
memmap_arr = np.memmap(filename, dtype='float64', mode='r+', shape=shape)
# 加法运算
memmap_arr += 1
# 乘法运算
memmap_arr *= 2
# 一元函数运算
memmap_arr = np.sqrt(memmap_arr)
# 关闭memmap数组
del memmap_arr
性能比较
使用memmap数组的最大优势在于可以处理大型数组,而不受内存限制。下面是一个简单的性能比较:
import numpy as np
import time
# 使用memmap数组
filename = 'memmap_array.dat'
shape = (10000, 10000)
memmap_arr = np.memmap(filename, dtype='float64', mode='w+', shape=shape)
start_time = time.time()
for i in range(shape[0]):
memmap_arr[i] = i
end_time = time.time()
print('Time taken using memmap array:', end_time - start_time)
# 使用普通numpy数组
normal_arr = np.zeros(shape)
start_time = time.time()
for i in range(shape[0]):
normal_arr[i] = i
end_time = time.time()
print('Time taken using normal array:', end_time - start_time)
在上述代码中,创建一个10000×10000的数组,分别使用memmap数组和普通numpy数组赋值操作,并比较耗时。可以看到,memmap数组的操作时间会比普通numpy数组略长,但对于处理大型数组来说,仍然是一个非常有效的方法。
总结
numpy中的memmap数组是一种能够将数组保存在磁盘上的特殊数组类型,可以在处理大型数组时节省内存空间,并提高性能。通过numpy.memmap函数可以方便地创建和操作memmap数组,在使用时需要注意对数组的操作会在磁盘上进行,可能会导致一定的性能损耗。对于处理大型数组的场景,使用memmap数组是一种非常有效的方法。