2013-09-30 13 views
9

Pracuję z raczej dużymi tablicami utworzonymi z dużych plików obrazów. Wystąpiły problemy z używaniem zbyt dużej ilości pamięci i postanowiłem spróbować użyć macierzy numpy.memmap zamiast standardowego numpy.array. Byłem w stanie stworzyć memmap i załadować dane do niego z mojego pliku obrazu w porcjach, ale nie jestem pewien, jak załadować wynik operacji do memmap.numpy.memmap z operacji numpy

Na przykład moje pliki graficzne są odczytywane jakojako binarne tablice całkowite. Napisałem funkcję, która buforuje (rozszerza) dowolny region komórek True o określoną liczbę komórek. Ta funkcja przekształca tablicę wejściową na Boolean przy użyciu array.astype(bool). Jak utworzyć nową tablicę Boolean utworzoną przez array.astype(bool) tablicę numpy.memmap?

Ponadto, jeśli komórka True znajduje się bliżej krawędzi tablicy wejściowej niż określony dystans bufora, funkcja doda wiersze i/lub kolumny do krawędzi tablicy, aby umożliwić utworzenie pełnego bufora wokół istniejącej tablicy. Komórka True. To zmienia kształt tablicy. Czy można zmienić kształt numpy.memmap?

Oto mój kod:

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

[w tej odpowiedzi] (http://stackoverflow.com/a/16597695/832621) wyjaśnione jest, jak radzić sobie z nieciągłymi danymi w memmapach, może to ci pomoże ... –

+0

@SaulloCastro - Dzięki za link. Nie jestem do końca pewien, jak to ma tutaj zastosowanie. Nie uważam, aby moja sytuacja była związana z nieciągłymi danymi, ale jestem nowy w kwestii numpy, więc mogę się mylić. – Brian

+0

Umieściłem link do tego pytania, ponieważ daje on pewne informacje o tym, jak pracować z przesunięciami w 'memmap', aby uzyskać dostęp do danego bloku danych, który będzie potrzebny w twoim przypadku. –

Odpowiedz

1

Pozwól mi spróbować odpowiedzieć na pierwszą część pytania. Ładowanie wyniku do datastore memmap.

Uwaga Zamierzam założyć, że istnieje plik memmap już na dysku - będzie to plik wejściowy. Nazywa MemmapInput, utworzony w następujący sposób:

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 

w Twoim przypadku plik wyjściowy nie może być obecna, ale za docs: „r +” Otwórz istniejący plik do odczytu i zapisu.

'w +' Utwórz lub zastąp istniejący plik do odczytu i zapisu.

Tak więc po pierwszym utworzeniu pliku memmap musi on zawierać 'w +', a następnie zmodyfikować/zastąpić plik, użyć 'r +', tylko kopie do odczytu można uzyskać za pomocą 'r'. Aby uzyskać więcej informacji, patrz http://docs.scipy.org/doc/numpy/reference/generated/numpy.memmap.html.

Teraz przeczytamy w tym pliku i wykonamy niektóre operacje na nim. Głównym celem jest załadowanie wyniku do pliku memamp, plik memmap musi najpierw zostać utworzony i dołączony do pliku.

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

robić, co chcesz z np fpOutput plików 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