Работа с большими данными в python и numpy, не хватает RAM, как сохранить частичные результаты на диске?

Я пытаюсь реализовать алгоритмы для 1000-мерных данных с 200k + datapoints в python. Я хочу использовать numpy, scipy, sklearn, networkx и другие полезные библиотеки. Я хочу выполнять такие операции, как попарное расстояние между всеми точками и делать кластеризацию во всех точках. Я реализовал рабочие алгоритмы, которые выполняют то, что я хочу, с разумной сложностью, но когда я пытаюсь масштабировать их ко всем моим данным, у меня заканчивается баран. Конечно, я делаю, создавая матрицу для парных расстояний на 200k + данных занимает много памяти.

Вот идет улов: я бы очень хотел сделать это на дрянных компьютерах с небольшим количеством барана.

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

Я хотел бы, чтобы мои алгоритмы могли работать, а затем вернулись через час или пять позже, и не застряли, потому что у него кончился баран! Я хотел бы реализовать это в python и иметь возможность использовать библиотеки numpy, scipy, sklearn и networkx. Я хотел бы иметь возможность рассчитать попарное расстояние до всех моих точек и т.д.

Возможно ли это? И как я могу это сделать, что я могу начать читать?

С уважением // Месмер

Ответ 1

С помощью numpy.memmap вы создаете массивы, непосредственно сопоставленные в файл:

import numpy
a = numpy.memmap('test.mymemmap', dtype='float32', mode='w+', shape=(200000,1000))
# here you will see a 762MB file created in your working directory    

Вы можете рассматривать его как обычный массив:   a + = 1000.

Можно даже назначить больше массивов в один и тот же файл, если это необходимо, и управлять им из взаимных источников. Но у меня есть некоторые хитроумные вещи. Чтобы открыть полный массив, сначала нужно "закрыть" предыдущий, используя del:

del a    
b = numpy.memmap('test.mymemmap', dtype='float32', mode='r+', shape=(200000,1000))

Но открытие только некоторой части массива позволяет добиться одновременного управления:

b = numpy.memmap('test.mymemmap', dtype='float32', mode='r+', shape=(2,1000))
b[1,5] = 123456.
print a[1,5]
#123456.0

Отлично! a был изменен вместе с b. И изменения уже записаны на диск.

Другая важная вещь, заслуживающая комментария, - это offset. Предположим, вы хотите взять не первые 2 строки в b, а строки 150000 и 150001.

b = numpy.memmap('test.mymemmap', dtype='float32', mode='r+', shape=(2,1000),
                 offset=150000*1000*32/8)
b[1,2] = 999999.
print a[150001,2]
#999999.0

Теперь вы можете получать и обновлять любую часть массива в одновременных операциях. Обратите внимание на размер байта, идущий в вычислении смещения. Итак, для "float64" этот пример будет 150000 * 1000 * 64/8.

Другие ссылки:

Ответ 2

Вы можете просто увеличить виртуальную память в ОС и использовать 64-битный питон, предоставляя ему 64-битные ОС.