python - 来自 numpy 操作的 numpy.memmap

标签 python arrays memory numpy

我正在处理从大图像文件创建的相当大的数组。我遇到了使用过多内存的问题,因此决定尝试使用 numpy.memmap 数组而不是标准的 numpy.array。我能够创建一个 memmap 并将数据从我的图像文件中分 block 加载到其中,但我不确定如何将操作结果加载到 memmap.

例如,我的图像文件被读入 numpy 作为二进制整数数组。我编写了一个函数,该函数将 True 单元格的任何区域缓冲(扩展)指定数量的单元格。此函数使用 array.astype(bool) 将输入数组转换为 Boolean。如何使 array.astype(bool) 创建的新 Boolean 数组成为 numpy.memmap 数组?

此外,如果有一个 True 单元格比指定的缓冲区距离更靠近输入数组的边缘,则该函数将向数组的边缘添加行和/或列以允许围绕现有 True 单元格的完整缓冲区。这会改变数组的形状。是否可以更改 numpy.memmap 的形状?

这是我的代码:

def getArray(dataset):
    '''Dataset is an instance of the GDALDataset class from the
    GDAL library for working with geospatial datasets

    '''
    chunks = readRaster.GetArrayParams(dataset, chunkSize=5000)
    datPath = re.sub(r'\.\w+$', '_temp.dat', dataset.GetDescription())
    pathExists = path.exists(datPath)
    arr = np.memmap(datPath, dtype=int, mode='r+',
                    shape=(dataset.RasterYSize, dataset.RasterXSize))
    if not pathExists:
        for chunk in chunks:
            xOff, yOff, xWidth, yWidth = chunk
            chunkArr = readRaster.GetArray(dataset, *chunk)
            arr[yOff:yOff + yWidth, xOff:xOff + xWidth] = chunkArr
    return arr

def Buffer(arr, dist, ring=False, full=True):
    '''Applies a buffer to any non-zero raster cells'''
    arr = arr.astype(bool)
    nzY, nzX = np.nonzero(arr)
    minY = np.amin(nzY)
    maxY = np.amax(nzY)
    minX = np.amin(nzX)
    maxX = np.amax(nzX)
    if minY - dist < 0:
        arr = np.vstack((np.zeros((abs(minY - dist), arr.shape[1]), bool),
                         arr))
    if maxY + dist >= arr.shape[0]:
        arr = np.vstack((arr,
                         np.zeros(((maxY + dist - arr.shape[0] + 1), arr.shape[1]), bool)))
    if minX - dist < 0:
        arr = np.hstack((np.zeros((arr.shape[0], abs(minX - dist)), bool),
                         arr))
    if maxX + dist >= arr.shape[1]:
        arr = np.hstack((arr,
                         np.zeros((arr.shape[0], (maxX + dist - arr.shape[1] + 1)), bool)))
    if dist >= 0: buffOp = binary_dilation
    else: buffOp = binary_erosion
    bufDist = abs(dist) * 2 + 1
    k = np.ones((bufDist, bufDist))
    bufArr = buffOp(arr, k)
    return bufArr.astype(int)

最佳答案

让我试着回答你问题的第一部分。将结果加载到 memmap 数据存储中。

注意我假设磁盘上已经有一个 memmap 文件——它将是输入文件。调用MemmapInput,创建如下:

fpInput = np.memmap('MemmapInput', dtype='bool', mode='w+', shape=(3,4))
del fpInput
fpOutput = np.memmap('MemmapOutput', dtype='bool', mode='w+', shape=(3,4))
del fpOutput

在您的情况下,输出文件可能不存在,但根据文档: 'r+' 打开现有文件进行读写。

‘w+’创建或覆盖现有文件进行读写。

所以第一次创建 memmap 文件时必须使用 'w+',之后修改/覆盖文件,使用 'r+',可以使用 'r' 获得只读副本。见 http://docs.scipy.org/doc/numpy/reference/generated/numpy.memmap.html了解更多信息。

现在我们将读入这个文件并对其执行一些操作。要点是将结果加载到memamp文件中,首先必须创建memmap文件并附加到文件中。

fpInput = np.memmap('MemmapInput', dtype='bool', mode='r', shape=(3,4))
fpOutput = np.memmap('MemmapOutput', dtype='bool', mode='r+', shape=(3,4))

用 fpOutput memmap 文件做任何你想做的事情,例如:

i,j = numpy.nonzero(fpInput==True)
for indexI in i:
  for indexJ in j:
    fpOutput[indexI-1,indexJ] = True
    fpOutput[indexI, indexJ-1] = True
    fpOutput[indexI+1, indexJ] = True
    fpOutput[indexI, indexJ+1] = True

关于python - 来自 numpy 操作的 numpy.memmap,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19098241/

相关文章:

python - 使用 GEKKO 移动水平估计和模型预测控制,对测量数据而不是平均测量使用react

python - 在pySpark中处理空数组(可选的二进制元素(UTF8)不是一个组)

Python-从csv文件中消除正则表达式匹配

python - Tesseract OCR,读取低分辨率/像素化字体(尤其是数字)

java - 如何在 Java 中将字符串插入二维字符串数组?

c - 在 C 中,将数字 i 添加到指针的行为是否添加 i*sizeof(datatype) 取决于编译器?

java - 自动将一个对象提升到老年代

c++ - 删除顺序、NULL 指针或内存泄漏

python - 索引超出尺寸 100 的轴 0 的范围

c - 如何正确处理 C 中的 malloc 失败,尤其是当存在多个 malloc 时?