Форма массива в numpy.asarray - PullRequest
0 голосов
/ 25 декабря 2018

Я пытаюсь рассчитать расстояния между точками в пространстве, используя scipy.distance.cdist.A содержит позиции точек Na, B содержит позиции точек Nb.

import numpy as np
from scipy.spatial import distanceNa=100
Na=100
Nb=500
A=np.random.rand(Na,3)
B=np.random.rand(Nb,3)
dist=distance.cdist(A,B)

даст мне расстояния между точками в A и B. Однако, когда Na> 20000 и Nb> 500 000, эта функция даст памятьошибка.Чтобы преодолеть это, я пытаюсь разделить А и В на более мелкие куски, рассчитать расстояния и объединить их:

import numpy as np
from scipy.spatial import distanceNa=100
Na=100
Nb=500
A=np.random.rand(Na,3)
B=np.random.rand(Nb,3)
As=np.array_split(A,10)
Bs=np.array_split(B,10)
np.asarray([distance.cdist(X,Y) for X in As for Y in Bs]).shape

Это возвращает (100, 10, 50).Я понимаю первое измерение, но почему 10 и 50?Что еще интереснее, если я изменю Na = 102, то на этот раз он вернется: (100,).В этом случае мой код:

QQ=np.asarray([distance.cdist(X,Y) for X in As for Y in Bs])
QQ.reshape(len(As),len(Bs)
JJ=[np.concatenate((QQ[i,:]),axis=1) for i in range(len(As))]
dist=np.concatenate((JJ[:]),axis=0)

Дает точно такую ​​же матрицу с distance.cdist (A, B).Но если Na = 100, форма Nb = 500 предыдущего массива будет (100,10,50) предотвращать изменение формы и объединение операций.Есть ли лучший питонский способ сделать это?В основном моя проблема в том, что функция cdist выдает ошибку памяти для больших массивов.

1 Ответ

0 голосов
/ 25 декабря 2018

Ваши As и Bs имеют длину 10, поэтому у вас Z = [distance.cdist(X,Y) for X in As for Y in Bs] есть длина 100.

Каждая из записей в этом списке представляет собой массив значений 10,50, так как каждый X имеет длину Na/10 = 10, а каждый Y имеет длину Nb/10 = 50.

Когда вы вызываете as_array, вы получаете пустой массив размером (100,10,50), поскольку список Z просто становится осью 0массива.

Обратите внимание, что первая запись Z соответствует первому блоку As с первым блоком Bs.Вторая запись Z соответствует первому блоку As со вторым блоком Bs.В общем, k -ая запись Z соответствует блоку Z%len(As) блока As и A//len(As) блока Bs.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...