В принципе, каков наилучший способ хранения и использования плотных матриц в python?
У меня есть проект, который генерирует метрики сходства между каждым элементом в массиве.
Каждый элемент является пользовательским классом и хранит указатель на другой класс и число, представляющее его "близость" к этому классу.
В настоящее время он прекрасно работает примерно до ~ 8000 элементов, после чего происходит сбой из-за нехватки памяти.
В основном, если вы предполагаете, что каждое сравнение использует ~ 30 (кажется точным, основываясь на тестировании) байтов для хранения подобия, это означает, что общая требуемая память составляет:
numItems^2 * itemSize = Memory
Таким образом, использование памяти является экспоненциальным в зависимости от количества элементов.
В моем случае объем памяти составляет ~ 30 байт на ссылку, поэтому:
8000 * 8000 * 30 = 1,920,000,000 bytes, or 1.9 GB
который находится на пределе памяти для одного потока.
Мне кажется, что должен быть более эффективный способ сделать это. Я смотрел на меммэппинг, но он уже требовал значительных вычислительных ресурсов только для генерации значений подобия, и узкое место в жестком диске кажется немного нелепым.
Редактировать
Я смотрел на Numpy и Scipy. К сожалению, они также не поддерживают очень большие массивы.
>>> np.zeros((20000,20000), dtype=np.uint16)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
MemoryError
>>>
Далее Редактировать
Numpy, кажется, популярен. Тем не менее, NumPy не будет делать то, что я хочу, по крайней мере без другого уровня абстракции.
Я не хочу для хранения чисел, я хочу хранить ссылки на классы. Numpy поддерживает объекты, но это не решает проблемы размера массива. Я привел numpy просто в качестве примера того, что не работает.
Любой совет?
Редактировать Ну, я просто переписал всю логику, чтобы он больше не сохранял никаких избыточных значений, уменьшая использование памяти с O*n^2
до O*((n*(n-1))/2)
.
По сути, вся эта история является версией проблемы рукопожатия , поэтому я перешел от хранения всех ссылок только к одной версии каждой ссылки.
Это не полное решение, но у меня обычно нет достаточно больших наборов данных, чтобы переполнить его, поэтому я думаю, что это сработает. PyTables действительно интересны, но я не знаю SQL, и, похоже, не существует какого-либо приятного традиционного способа нарезки или индексации для доступа к данным таблицы. Я могу вернуться к этому вопросу в будущем.