Nie używaj tablic obiektów w numpy do takich rzeczy.
Pokonują podstawowy cel tablicy numpy, a gdy są przydatne w niewielkiej liczbie sytuacji, prawie zawsze są złym wyborem.
Tak, uzyskanie dostępu do pojedynczego elementu tablicy numpy w python lub iterowanie przez tablicę numpy w pythonie jest wolniejsze niż równoważna operacja z list
. (Dlatego nigdy nie powinieneś robić czegoś takiego jak y = [item * 2 for item in x]
, gdy x
jest tablicą numpy.)
Macierze obiektów Numpy będą miały nieco mniejszy narzut pamięci niż lista, ale jeśli przechowujesz wiele pojedynczych obiektów Pythona, Najpierw napotkasz inne problemy z pamięcią.
Numpy jest przede wszystkim efektywnym pod względem pamięci, wielowymiarowym pojemnikiem tablicowym dla jednolitych danych liczbowych. Jeśli chcesz przechowywać dowolne obiekty w tablicy numpy, prawdopodobnie potrzebujesz listy.
Chodzi mi o to, że jeśli chcesz efektywnie używać numpy, może być konieczne ponowne przemyślenie struktury.
Zamiast przechowywać każdą instancję obiektu w tablicy numpy, przechowuj swoje dane numeryczne w tablicy numpy, a jeśli potrzebujesz osobnych obiektów dla każdego wiersza/kolumny/cokolwiek, przechowuj indeks do tej tablicy w każdym wystąpieniu.
W ten sposób można szybko pracować z tablicami numerycznymi (np. Za pomocą numpy zamiast z listą).
Jako szybki przykład tego, co mówię, tu jest trywialny przykład bez użycia 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
i podobny przykład za pomocą numpy tablice:
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
Istnieją inne sposoby Aby to zrobić (możesz chcieć uniknąć zapisywania odwołania do konkretnej tablicy w każdym point
, ale mam nadzieję, że jest to przydatny przykład.
Zwróć uwagę na różnicę prędkości, z jaką działają. Na mojej maszynie różnica wynosi 5 sekund w przypadku wersji numpy w porównaniu z 60 sekund w przypadku wersji z czystym pythonem.