来自numpy操作的numpy.memmap

时间:2013-09-30 15:36:48

标签: python arrays memory numpy

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

例如,我的图像文件作为二进制整数数组读入numpy。我编写了一个函数,用于缓冲(扩展)True个单元格的任何区域指定数量的单元格。此函数使用Boolean将输入数组转换为array.astype(bool)。如何创建由Boolean array.astype(bool)数组创建的新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)

1 个答案:

答案 0 :(得分:1)

让我试着回答你问题的第一部分。将结果加载到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

在您的情况下,输出文件可能不存在,但是根据文档: &#39; R +&#39;打开现有文件进行读写。

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

因此,第一次创建memmap文件时,必须使用&#39; w +&#39;然后修改/覆盖文件,使用&#39; r +&#39;,只读副本可以通过“r&#39;获得。有关详细信息,请参阅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