¿Cómo se puede calcular un ráster de manera eficiente (en Python), dado un conjunto que consiste en miles de millones de cuadros delimitadores (leídos secuencialmente de un archivo), y dado que los valores de ráster para cada celda deben dar el número de cuadros delimitadores superpuestos?
Para una trama 4000 * 4000
He cronometrado la creación de matriz numpy:
$ python -m timeit 'import numpy' 'a = numpy.zeros(shape=(4000,4000))'
10 loops, best of 3: 51.7 msec per loop
Creación de matriz de python estándar:
$ python -m timeit 'a = 4000*[0]' 'for i in range(4000):' ' a[i]=4000*[0]'
10 loops, best of 3: 218 msec per loop
Así que numpy es más rápido, pero aún 50 ms por ciclo, con mil millones de iteraciones, produce un tiempo de ejecución igual a aproximadamente un año (0.05 ms * 1000000000/60/60/24/365 = 1.5 años)
Por lo tanto, no es una opción probar cada polígono. ¿Cuál es un enfoque típico para este problema?
Respuestas:
Su
timeit
incluye la importación numpy, que agregaría algo de sobrecarga. Entonces, ¿por qué no escribe el código para un subconjunto de los cuadros delimitadores y cronometra ese ciclo, luego lo multiplica para estimar el tiempo total de ejecución?Resolverlo en una sola computadora es, por naturaleza, serial, y con una operación relativamente simple, es posible que no obtenga una optimización significativa de un algoritmo ya simple. Podría intentar dividirlo en una especie de operación manual de reducción de mapas (sé que tiene una advertencia de "no reducción de mapas") y ejecutar tantas instancias como núcleos. Hacer mosaicos / fusionar n rásteres (el paso de reducción) es una operación trivialmente rápida. Probablemente será menos doloroso codificar que una solución multiproceso.
Alternativamente (o adicionalmente), podría escribir un programa para combinar ciertos cuadros delimitadores, como los superpuestos o anidados; esto requeriría un índice espacial. Si no tiene uno, puede ser beneficioso crear uno, especialmente si termina paralelizando localmente el algoritmo principal.
Además, no descarte la paralelización de varias computadoras de la mano. Si su mejor estimación es más de un año, entonces necesita sumar cuánto dinero costará su tiempo en la ejecución de la versión para una sola computadora, y compararlo con la contratación de un tiempo de computación en la nube. Como dice @whuber, 1024 GPU mordirán los datos tan rápido que te costará casi nada, incluso si pasas una semana dando vueltas a CUDA. Si es su jefe quien le prohíbe probarlo en más de una computadora, haga el análisis de costos y entréguele algunos números concretos; luego sopesará el valor de los datos con el valor de su tiempo.
fuente
Si entendí correctamente, lo que quieres es como representar tu conjunto de miles de millones de cuadros delimitadores en una imagen. Excepto que en lugar de "pintar" cada polígono sobre una celda (píxel), los cuenta (o acumula).
Puede usar un código (relativamente) simple (en OpenGL, Vulcan, Direct3D) para representar los polígonos y acumular el recuento en el búfer de la plantilla. Tenga cuidado para que los polígonos caigan exactamente en los límites de los píxeles y elija un tipo de datos para el búfer de la plantilla para que el recuento no se desborde. Esperaría que se ejecute en unos segundos en una sola GPU ...
fuente