2013-09-30 231 views
9

我正在使用大型圖像文件創建的相當大的數組。我在使用太多內存時遇到了問題,並決定嘗試使用numpy.memmap陣列而不是標準numpy.array。我能夠創建一個memmap並從我的映像文件中以塊加載數據,但我不確定如何將操作結果加載到memmapnumpy操作的numpy.memmap

例如,我的圖像文件被讀入numpy作爲二進制整數數組。我已經寫了一個函數,用於指定數量的單元格緩存(擴展)任何區域的True單元格。該函數使用array.astype(bool)將輸入數組轉換爲Boolean。我將如何使由array.astype(bool) a numpy.memmap數組創建新的Boolean陣列?

另外,如果有一個True單元靠近輸入數組的邊緣而不是指定的緩衝距離,該函數會將行和/或列添加到數組的邊緣以允許在現有的True cell。這改變了數組的形狀。是否可以改變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) 
+0

[這個答案](http://stackoverflow.com/a/16597695/832621)闡述瞭如何應對與不連續的數據在memmaps中,也許它會幫助你... –

+0

@SaulloCastro - 感謝您的鏈接。我不確定這裏適用的是如何。我不認爲我的情況與不連續的數據有關,但我是新來的numpy,所以我可能是錯的。 – Brian

+0

我發佈了該問題的鏈接,因爲它提供了一些關於如何使用偏移到m​​emmap中的信息,以便訪問給定的數據塊,這將在您的情況下需要。 –

回答

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 

在你的情況下,輸出文件可能不存在,但每個文檔: 「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