Вставка строк в пустой массив с помощью Numpy

#python #arrays #numpy

#python #массивы #numpy

Вопрос:

Здравствуйте, в настоящее время я пытаюсь преобразовать этот массив

 test=np.array([[0,0],[0,1],[1,1],[3,0]])
  

и использование расстояния Манхэттена для преобразования этого массива в эту форму

 [0., 1., 2., 3.] 
[1., 0., 1., 4.]
[2., 1., 0., 3.,
[3., 4., 3., 0.]
  

код выглядит следующим образом

 list_x=[]
newarray=np.array([])
length=len(test)
for i in range(length):
    for j in range(length):
        print('i=',i)
        print('j=',j)
        var=sum(abs(a-b) for a,b in zip(test[i],test[j]))
        list_x.append(var)
    newarray= np.append(newarray,list_x,axis = 0) 
    list_x=[]
    
  

но результат кода продолжает давать мне это:

 array([0., 1., 2., 3., 1., 0., 1., 4., 2., 1., 0., 3., 3., 4., 3., 0.])
  

есть ли проблема в моем np.append(), которая мешает преобразовать его в массив 4 * 4 shap?

Ответ №1:

Вы могли бы использовать scikit-learn manhattan_distances для получения всех попарных расстояний Манхэттена, упростив вышесказанное до одного вызова функции:

 from sklearn.metrics.pairwise import manhattan_distances

manhattan_distances(test)
array([[0., 1., 2., 3.],
       [1., 0., 1., 4.],
       [2., 1., 0., 3.],
       [3., 4., 3., 0.]])
  

Если вы хотите получить расстояние с помощью цикла for, я бы посоветовал вам вместо этого использовать списки python. Чтобы в итоге получить вложенный список, сгенерируйте внутренний список с расстояниями строки до остальных и добавляйте его во внешний список на каждой итерации:

 out=[]
for i in range(length):
    new_row = []
    for j in range(length):
        var=sum(abs(a-b) for a,b in zip(test[i],test[j]))
        new_row.append(var)
    out.append(new_row)

print(out)
# [[0, 1, 2, 3], [1, 0, 1, 4], [2, 1, 0, 3], [3, 4, 3, 0]]
  

Комментарии:

1. или используйте свой оригинал… z = np.array([0., 1., 2., 3., 1., 0., 1., 4., 2., 1., 0., 3., 3., 4., 3., 0.]) и z.изменить форму (4,4)

Ответ №2:

Другой способ сделать это — использовать Scipy:

 from scipy.spatial.distance import cdist
cdist(test,test,'cityblock')
  

вывод:

 [[0. 1. 2. 3.]
 [1. 0. 1. 4.]
 [2. 1. 0. 3.]
 [3. 4. 3. 0.]]
  

Сравнение:

 #@ehsan's solution
def m1(test):
  return cdist(test,test,'cityblock')

#@yatu's solution
def m2(test):
  return manhattan_distances(test)

in_ = [np.random.randint(0,10,(n,2)) for n in [10,100,1000,10000]]
  

Для больших массивов они, похоже, имеют аналогичную производительность, но для меньшего массива (около 1000 строк) m1 кажется быстрее.

введите описание изображения здесь

Комментарии:

1. Я знаю функцию cdist, но цель этой задачи — вручную выровнять расстояние до Манхэттена, и у меня проблема только в функции добавления

2. @RAbeeq Тогда я неправильно понял проблему. Обязательно ли использовать циклы? вы все еще можете реализовать это с помощью numpy без циклов. Цикл массива вообще не рекомендуется и выполняется медленно. Если вам нужны циклы, я думаю, что ответ Яту охватывает это. Если вам не нужно использовать циклы, я могу помочь реализовать это с помощью массивов.

3. нет необходимости, но благодарю вас за помощь, я действительно благодарю вас