2013-09-30 12 views
9

Sto lavorando con array piuttosto grandi creati da file di immagine di grandi dimensioni. Stavo avendo problemi con l'utilizzo di troppa memoria e ho deciso di provare a utilizzare gli array numpy.memmap anziché lo standard numpy.array. Sono stato in grado di creare un memmap e caricare i dati in esso dal mio file immagine in blocchi, ma non sono sicuro di come caricare il risultato di un'operazione in un memmap.numpy.memmap da operazioni numpy

Ad esempio, i miei file di immagine vengono letti in numpy come array di numeri interi binari. Ho scritto una funzione che bufferizza (espande) qualsiasi regione di celle True di un numero specificato di celle. Questa funzione converte l'array di input in Boolean utilizzando array.astype(bool). Come posso creare la nuova matrice Boolean creata da array.astype(bool) una matrice numpy.memmap?

Inoltre, se c'è una cella True più vicina al bordo della matrice di input rispetto alla distanza del buffer specificata, la funzione aggiungerà righe e/o colonne al bordo della matrice per consentire un buffer completo attorno alla esistente True cell. Questo cambia la forma della matrice. È possibile modificare la forma di un numpy.memmap?

Ecco il mio codice:

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

[in questa risposta] (http://stackoverflow.com/a/16597695/832621) è spiegato come affrontare con dati discontinui in memmaps, forse ti aiuterà ... –

+0

@ SaulloCastro - Grazie per il link. Non sono davvero sicuro di come si applica qui. Non considero la mia situazione correlata a dati discontinui, ma sono nuova a numpy, quindi potrei sbagliarmi. – Brian

+0

Ho postato il collegamento a quella domanda poiché fornisce alcune informazioni su come lavorare con gli offset in un 'memmap', per accedere a un dato blocco di dati, che sarà necessario nel tuo caso. –

risposta

1

Vorrei provare a rispondere alla prima parte della sua domanda. Caricamento di un risultato in un datastore memmap.

Nota Si supporrà che sul disco sia già presente un file memmap, che sarà il file di input. Chiamato MemmapInput, creato come segue:

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 

Nel tuo caso il file di output potrebbe non essere presente, ma per la documentazione: 'r +' Apri file esistente in lettura e scrittura.

'w +' Crea o sovrascrive il file esistente per la lettura e la scrittura.

Quindi la prima volta che si crea un file memmap deve essere con un "w +", in seguito per modificare/sovrascrivere il file, utilizzare 'r +', le copie di Readonly possono essere ottenute con 'r'. Vedi http://docs.scipy.org/doc/numpy/reference/generated/numpy.memmap.html per maggiori informazioni.

Ora leggeremo in questo file ed eseguiremo alcune operazioni su di esso. Il punto principale è caricare un risultato in un file memamp, il file memmap deve prima essere creato e allegato a un file.

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

fare quello che vuoi con il file memmap fpOutput esempio:

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