Sto lavorando su Ubuntu 14.04 con Python 3.4 (Numpy 1.9.2 e PIL.Image 1.1.7). Ecco cosa faccio:Perché Python si blocca quando provo a sommare questo array numpy?
>>> from PIL import Image
>>> import numpy as np
>>> img = Image.open("./tifs/18015.pdf_001.tif")
>>> arr = np.asarray(img)
>>> np.shape(arr)
(5847, 4133)
>>> arr.dtype
dtype('bool')
# all of the following four cases where I incrementally increase
# the number of rows to 700 are done instantly
>>> v = arr[1:100,1:100].sum(axis=0)
>>> v = arr[1:500,1:100].sum(axis=0)
>>> v = arr[1:600,1:100].sum(axis=0)
>>> v = arr[1:700,1:100].sum(axis=0)
# but suddenly this line makes Python crash
>>> v = arr[1:800,1:100].sum(axis=0)
fish: Job 1, “python3” terminated by signal SIGSEGV (Address boundary error)
A me sembra come se Python esaurisse la memoria all'improvviso. In questo caso, come posso allocare più memoria in Python? Come posso vedere da htop la mia capacità di memoria da 32 GB non è neanche lontanamente depleated.
È possibile scaricare l'immagine TIFF here.
Se creo un array booleano vuoto, impostare i pixel esplicitamente e quindi applicare la sommatoria - allora funziona:
>>> arr = np.empty((h,w), dtype=bool)
>>> arr.setflags(write=True)
>>> for r in range(h):
>>> for c in range(w):
>>> arr.itemset((r,c), img.getpixel((c,r)))
>>> v=arr.sum(axis=0)
>>> v.mean()
5726.8618436970719
>>> arr.shape
(5847, 4133)
Ma questa "soluzione" non è molto soddisfacente come la copia di ogni pixel prende troppo lungo - forse c'è un metodo più veloce?
un errore di segmentazione * sempre * indica un bug. Anche se Python fosse a corto di memoria, sarebbe un bug per farlo andare in crash con un errore di segmentazione invece di lanciare un errore di memoria insufficiente. –
È concepibile che si stia esaurendo lo spazio disponibile. Il fatto che non lo si faccia nel caso casuale 10000 x 10000 potrebbe indicare una differenza nell'algoritmo utilizzato per le sezioni dell'array rispetto a quello utilizzato per interi array. Se per le sezioni si utilizzava un algoritmo ricorsivo, una sezione di array con molti segmenti discontinui potrebbe recidiva troppo profondamente e esaurire la pila. Questo è tutto speculativo, ovviamente. –
Anche il primo caso si arresta in modo anomalo quando non è in sezione e il secondo caso non si arresta in modo anomalo anche se in sezione. – Raffael