2012-01-04 2 views
3

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

>>> input_array.shape 
(50, 200000) 
>>> random_array = np.random.normal(size=(200000, 300)) 
>>> output_array = np.dot(input_array, random_array) 

К сожалению, random_array занимает много памяти, и моя машина начинает обменивать. Мне кажется, что мне действительно не нужно все сразу random_array; в теории, я должен был бы лениво генерировать его во время вычисления точечного продукта ... но я не могу понять, как это сделать.

Как уменьшить объем памяти для расчета output_array от input_array?

+0

Это упрощенный пример, или вы на самом деле усеивание в большой массив нормально распределенные случайных числа? Способ создания «random_array» может иметь значение. –

+0

@ Давид Заславский не упрощенный пример - это именно то, что я хочу сделать. Метод, который допускает изменения в генерации 'random_array', является бонусом, но не обязательным. –

+0

Имея игру с этим, я не уверен, что это возможно - 'np.dot' должен знать размеры всех своих входов (в виде 2D-точечного произведения == матричное умножение). В любом случае я не вижу (простой) способ использования генератора в 'np.dot'. – Yuushi

ответ

4

Это, очевидно, не является самым быстрым решением, но вы пробовали:

m, inner = input_array.shape 
n = 300 
out = np.empty((m, n)) 
for i in xrange(n): 
    out[:, i] = np.dot(input_array, np.random.normal(size=inner)) 
+0

Thanks; не знаю, почему этот разумный подход не пришел ко мне. :) Это определенно не быстро ... но в моем случае это терпимый компромисс. –

2

Это может быть ситуация, когда использование cython может уменьшить использование вашей памяти. Вы можете генерировать случайные числа «на лету» и накапливать результат по ходу дела. У меня нет времени писать и тестировать полную функцию, но вы обязательно захотите использовать randomkit (библиотека, которую numpy использует под капотом) на уровне c.

Вы посмотрите на какой-то пример кода, который я написал для другого приложения можно увидеть, как обернуть randomkit:

https://github.com/synapticarbors/pylangevin-integrator/blob/master/cIntegrator.pyx

А также проверить, как умножение матриц осуществляется в следующей статье на Cython:

http://conference.scipy.org/proceedings/SciPy2009/paper_2/full_text.pdf

Вместо того, чтобы оба массивы в качестве входов, просто input_array как один, а затем в способе, генерируют небольшие куски случайного массива, когда вы идете.

Извините, если это всего лишь эскиз вместо фактического кода, но, надеюсь, этого достаточно, чтобы вы начали.

+0

Это отличный ответ - очень полезные указатели. Я думаю, что в краткосрочной перспективе, обходное решение @ Bago будет достаточным, но это хорошо, что у меня в рукаве. –

Смежные вопросы