2013-09-30 5 views
9

Ich arbeite mit ziemlich großen Arrays aus großen Bilddateien. Ich hatte Probleme mit zu viel Speicher und entschied mich, numpy.memmap Arrays anstelle des Standards numpy.array zu verwenden. Ich war in der Lage, eine memmap zu erstellen und laden Sie die Daten aus meiner Bilddatei in Stücke, aber ich bin mir nicht sicher, wie Sie das Ergebnis einer Operation in eine memmap laden.numpy.memmap aus numpy Operationen

Zum Beispiel werden meine Bilddateien in numpy als binäre Integer-Arrays gelesen. Ich habe eine Funktion geschrieben, die jede Region von True Zellen mit einer bestimmten Anzahl von Zellen puffert (erweitert). Diese Funktion konvertiert das Eingangs-Array unter Verwendung von array.astype(bool) in . Wie würde ich das neue Array erstellen, das von array.astype(bool) ein numpy.memmap Array erstellt wird?

Wenn sich eine Zelle True näher am Rand des Eingabearrays befindet als der angegebene Pufferabstand, fügt die Funktion Zeilen und/oder Spalten am Rand des Arrays hinzu, um einen vollständigen Puffer um das vorhandene Array herum zu ermöglichen True Zelle. Dies ändert die Form des Arrays. Ist es möglich, die Form eines numpy.memmap zu ändern?

Hier ist mein Code:

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 dieser Antwort] (http://stackoverflow.com/a/16597695/832621) wird erläutert, wie zu tun mit diskontinuierlichen Daten in Memmaps, vielleicht wird es Ihnen helfen ... –

+0

@SaulloCastro - Danke für den Link. Ich bin mir nicht sicher, wie das hier ist. Ich denke nicht, dass meine Situation mit diskontinuierlichen Daten zu tun hat, aber ich bin neu in der Anzahl, daher kann ich mich irren. – Brian

+0

Ich habe den Link zu dieser Frage gepostet, da er einige Informationen darüber enthält, wie man mit Offsets in einer 'memmap' arbeitet, um auf einen bestimmten Datenblock zuzugreifen, der in Ihrem Fall benötigt wird. –

Antwort

1

Lassen Sie mich versuchen, den ersten Teil Ihrer Frage zu beantworten. Laden eines Ergebnisses in einen Memmap-Datenspeicher

Hinweis Ich gehe davon aus, dass sich bereits eine memmap-Datei auf der Festplatte befindet - es wird die Eingabedatei sein. Genannt MemmapInput, wie folgt erstellt:

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 

In Ihrem Fall die Ausgabedatei nicht vorhanden sein könnte, aber nach dem docs: ‚r +‘ Open vorhandene Datei zum Lesen und Schreiben.

'w +' Erstellen oder überschreiben Sie vorhandene Datei zum Lesen und Schreiben.

Wenn Sie also zum ersten Mal eine memmap-Datei erstellen, muss sie mit einem 'w +' versehen sein, danach die Datei ändern/überschreiben, 'r +' verwenden, Nur-Lese-Kopien erhalten Sie mit 'r'. Weitere Informationen finden Sie unter http://docs.scipy.org/doc/numpy/reference/generated/numpy.memmap.html.

Jetzt werden wir in dieser Datei lesen und einige Operationen darauf ausführen. Der Hauptpunkt ist, ein Ergebnis in eine Memamp-Datei zu laden, die Memmap-Datei muss zuerst erstellt und an eine Datei angehängt werden.

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

tun, was Sie mit der fpOutput memmap Datei zB wollen:

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