Я думаю, что у меня большой сценарий данных (N = 1e6 и размер = 3). Мне нужно несколько раз манипулировать матрицей, например einsum, инвертирование матрицы и т. Д. В моем коде. Чтобы дать идею, я хочу сделать что-то вроде ниже.Массирование матрицы больших данных Python
import numpy.random as rd
ndata, kdata = 1e6, 1e5
x = rd.normal(0,1,(ndata, kdata,3,3))
y = rd.normal(0,1,(ndata, kdata,3,3))
Для малых NDATA, kdata следующее было бы эффективным и удобным подход,
xy = einsum('pqrs, pqsu -> pqru', x, y)
Поскольку у меня есть большой NDATA и kdata выше подхода становится связанной проблемой памяти так, следующая ставка будет скалярное произведение с вложенный для цикла по NDATA и kdata следующим образом:
xyloop1 = np.empty((ndata, kdata, 3, 3))
for j in xrange(ndata):
for k in xrange(kdata):
xyloop1[j,k] = np.dot(x[j,k], y[j,k])
Учитывая то, что я преподавала петлю противные в питоне. Кроме того, я хочу использовать преимущество Numpy так думал блок матричного подхода был бы предпочтительнее что-то вроде следующие:
nstep = 200
ndiv = ndata/nstep
kstep = 200
kdiv = kdata/kstep
xyloop2 = np.empty((ndata, kdata, 3, 3))
for j in xrange(ndiv):
ji, jf = j*nstep, (j+1)*nstep
for k in xrange(kdiv):
ki, kf = k*kstep, (k+1)*kstep
xyloop2[ji:jf,ki:kf] = einsum('pqrs, pqsu -> pqru', x[ji:jf,ki:kf], y[ji:jf,ki:kf])
Кроме того, мне нужен этот х или xyloop1 или xyloop2 для моего дальнейшего расчета. Поэтому я должен писать и читать его после каждого вычисления. Учитывая пропускную способность системного ввода-вывода, вы считаете, что наилучшим подходом будет подход 3, поскольку это означает меньше ввода-вывода, а также небольшое количество итераций по сравнению с подходом 2? Если у вас есть какая-либо другая идея или вам нужна дополнительная информация, пожалуйста, дайте мне знать.
Я новичок в стеке, поэтому, пожалуйста, будьте нежны со мной :). Любая помощь будет высоко оценена. BTW Я пытаюсь решить проблему моделирования смеси для больших данных. Благодаря!
Это очень хороший вопрос, но в конец, вы единственный, кто может ответить на него правильно. :) Просматривайте вещи и смотрите, что быстрее для вашей конкретной проблемы. Оба являются хорошими подходами. Именно тот подход, который будет самым быстрым, будет в значительной степени зависеть от размера ваших входных данных и того, что вы делаете. Вы также можете рассмотреть возможность изменения вашей первой версии для векторизации вычисления вдоль одной оси и петли над другой. Векторизация - это компромисс между использованием памяти и скоростью. Часто бывает лучше удалить только одну часть вложенного цикла, если проблема с памятью является проблемой. –
Спасибо @JoeKington за комментарий. Для ясности я упомянул только точечный продукт во внутреннем контуре. В таком случае, как и указанная векторизация внутренней петли, безусловно, путь. Тем не менее, на самом деле я делаю несколько матричных алгебр, включая инверсию, транспонирование, пару более точечных продуктов и т. Д. Поэтому я предполагаю, что векторизация или использование понимания списка для внутреннего цикла не является хорошей идеей. В отношении первой части вашего комментария я сделаю профилирование и опубликую его. Мне нравится добавить, что использование ** cvxopt ** пакета LAPACK и BLAS и подхода 2 равно скорости приближения 3. – evernomer