Хранение объектов Python в списке Python по сравнению с массивом Numpy с фиксированной длиной

Выполняя некоторые работы по биоинформатике, я размышлял над последствиями хранения экземпляров объектов в массиве Numpy, а не в списке Python, но во всех тестах, которые я выполнил, производительность была хуже в каждом случае. Я использую CPython. Кто-нибудь знает причину?

В частности:

  • Почему deque реализован как связанный список вместо кругового массива?
  • Почему (0-6) -6 = False?
  • C Python: запуск кода Python в контексте
  • Почему медленнее перебирать небольшую строку, чем небольшой список?
  • Почему кортеж (set ()) == tuple (set ()) 85% времени с включенной хэш-рандомизацией?
  • Как загрузить C # dll в python?
    • Каковы влияние производительности использования массива с фиксированной длиной numpy.ndarray(dtype=object) сравнению с обычным списком Python? Начальные тесты, выполненные мной, показали, что доступ к элементам массива Numpy был медленнее, чем итерация через список Python, особенно при использовании методов объектов.
    • Почему быстрее создавать объекты, используя понимание списка, например [ X() for i in range(n) ] вместо numpy.empty(size=n, dtype=object) ?
    • Каковы издержки памяти для каждого из них? Я не смог проверить это. Мои классы широко используют __slots__ , если это имеет какое-то влияние.

  • Легкий способ проверить, находится ли каждый элемент в массиве numpy между двумя значениями?
  • Numpy: Row Wise Уникальные элементы
  • Построение графика с помощью Python
  • TA-Lib numpy "AssertionError: реальный не двойной"
  • Повторить массив NumPy без репликации данных?
  • Почему код Python работает быстрее в функции?
  • One Solution collect form web for “Хранение объектов Python в списке Python по сравнению с массивом Numpy с фиксированной длиной”

    Не используйте массивы объектов в numpy для таких вещей.

    Они побеждают основную цель массива numpy, и, хотя они полезны в крошечных кучах ситуаций, они почти всегда являются плохим выбором.

    Да, доступ к отдельному элементу массива numpy в python или итерация через массив numpy в python происходит медленнее, чем эквивалентная операция со list . (Вот почему вы никогда не должны делать что-то вроде y = [item * 2 for item in x] когда x является массивом numpy.)

    Массивы объектов Numpy будут иметь немного более низкую накладную память, чем список, но если вы храните много отдельных объектов python, сначала вы столкнетесь с другими проблемами памяти.

    Numpy – это, прежде всего, массив памяти, многомерный массив для равномерных числовых данных. Если вы хотите удерживать произвольные объекты в массиве numpy, вам, скорее всего, нужен список.


    Я хочу сказать, что если вы хотите эффективно использовать numpy, вам может потребоваться переосмыслить, как вы структурируете вещи.

    Вместо хранения каждого экземпляра объекта в массиве numpy сохраните свои числовые данные в массиве numpy, и если вам нужны отдельные объекты для каждой строки / столбца / независимо, сохраните индекс в этом массиве в каждом экземпляре.

    Таким образом, вы можете быстро работать с числовыми массивами (т. Е. Использовать numpy вместо списков).

    В качестве краткого примера того, что я говорю, вот тривиальный пример без использования 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 

    И аналогичный пример с использованием массивов 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 

    Существуют и другие способы сделать это (возможно, вы захотите избежать ссылки на конкретный массив numpy в каждой point , например), но я надеюсь, что это полезный пример.

    Обратите внимание на разницу в скорости, с которой они работают. На моей машине разница составляет 5 секунд для версии numpy и 60 секунд для версии pure-python.

    Python - лучший язык программирования в мире.