No utilice matrices de objetos en numpy para cosas como esta.
Derrotan el propósito básico de una matriz numpy, y si bien son útiles en un pequeño puñado de situaciones, casi siempre son una mala elección.
Sí, acceder a un elemento individual de una matriz numpy en python o iterar a través de una matriz numpy en python es más lento que la operación equivalente con list
. (Razón por la cual nunca se debe hacer algo como y = [item * 2 for item in x]
cuando x
es una matriz numpy.)
numpy matrices de objetos tendrán una sobrecarga de memoria ligeramente inferior a una lista, pero si usted está almacenando que muchos objetos pitón individuales, Primero se encontrará con otros problemas de memoria.
Numpy es, ante todo, un contenedor de matriz multidimensional eficiente en cuanto a la memoria para datos numéricos uniformes. Si desea mantener objetos arbitrarios en una matriz numpy, es probable que desee una lista.
Mi punto es que si desea utilizar numpy efectivamente, puede que tenga que volver a pensar en cómo se está estructurando cosas.
En lugar de almacenar cada instancia de objeto en una matriz numpy, almacenar sus datos numéricos en una matriz numpy, y si necesita objetos separados para cada fila/columna/lo que sea, almacenar un índice dentro de esa matriz en cada caso.
De esta forma puede operar los arreglos numéricos rápidamente (es decir, usando numpy en lugar de listas de comprensión).
Como un ejemplo rápido de lo que estoy hablando, he aquí un ejemplo trivial sin utilizar numpy:
from random import random
class PointSet(object):
def __init__(self, numpoints):
self.points = [Point(random(), random()) for _ in xrange(numpoints)]
def update(self):
for point in self.points:
point.x += random() - 0.5
point.y += random() - 0.5
class Point(object):
def __init__(self, x, y):
self.x = x
self.y = y
points = PointSet(100000)
point = points.points[10]
for _ in xrange(1000):
points.update()
print 'Position of one point out of 100000:', point.x, point.y
Y un ejemplo similar utilizando matrices numpy:
import numpy as np
class PointSet(object):
def __init__(self, numpoints):
self.coords = np.random.random((numpoints, 2))
self.points = [Point(i, self.coords) for i in xrange(numpoints)]
def update(self):
"""Update along a random walk."""
# The "+=" is crucial here... We have to update "coords" in-place, in
# this case.
self.coords += np.random.random(self.coords.shape) - 0.5
class Point(object):
def __init__(self, i, coords):
self.i = i
self.coords = coords
@property
def x(self):
return self.coords[self.i,0]
@property
def y(self):
return self.coords[self.i,1]
points = PointSet(100000)
point = points.points[10]
for _ in xrange(1000):
points.update()
print 'Position of one point out of 100000:', point.x, point.y
Hay otras maneras para hacer esto (es posible que desee evitar el almacenamiento de una referencia a un matriz numpy específica en cada point
, por ejemplo), pero espero que sea un ejemplo útil.
Tenga en cuenta la diferencia en la velocidad a la que se ejecutan. En mi máquina, es una diferencia de 5 segundos para la versión de numpy frente a 60 segundos para la versión de python puro.