Обновление массива NumPy с помощью вычислений, выполненных в списке массивов. - PullRequest
1 голос
/ 15 марта 2019

У меня есть список длиной 50, заполненный массивами длины 5. Я пытаюсь вычислить расстояние между каждым массивом в списке и обновить массив с пустыми значениями.

Расчет расстояния - это просто получение квадратного корня из суммы квадратов расстояния между каждым элементом в массивах.

Когда я пытаюсь:

primaryCustomer = np.zeros(shape = (50,50))

for customer in range(0,50):
  for pair in range(0,50):
    thisCustomer = [0 for i in range(51)]
    if customer == pair:
      thisCustomer[pair] = 999
    else:

      calculateScores = (((Customer[customer][0]-Customer[pair][0])**2 
                            + (Customer[customer][1]-Customer[pair][1])**2 
                            + (Customer[customer][2]-Customer[pair][2])**2 
                            + (Customer[customer][3]-Customer[pair][3])**2 
                            + (Customer[customer][4]-Customer[pair][4])**2 )**(0.5))
      thisCustomer[pair] = calculateScores
  np.append(primaryCustomer, thisCustomer)

происходит пара вещей:

  • Последняя итерация thisCustomer возвращает список всех нулей, кроме последнего элемента 999 (соответствует части if в приведенном выше утверждении). Итак, я знаю, что может обновить список, но он не делает это в части else.
  • Я хочу, чтобы массив 'primaryCustomer' обновлялся с помощью Customer в качестве индекса и всех вычисленных оценок с каждой парой в качестве значений строки, но, похоже, он не обновляется вообще

Любые изменения, которые я делаю, например, пытаясь трактовать thisCustomer в цикле как массив вместо списка и добавлять к нему, в конечном итоге фиксируют одну область, а другие - еще хуже.

Вот как я получаю данные клиента:

Customer = [[0,0,0,0,0] for i in range(51)]

for n in range(51):
  Customer[n] = np.ones(5)
  Customer[n][randint(2,4):5] = 0
  np.random.shuffle(Customer[n])

Я знаю, что могут быть упакованные способы сделать это, но я пытаюсь понять, как такие вещи, как KNN, работают в фоновом режиме, поэтому я бы хотел продолжить выяснение логики в циклах, как описано выше. Кроме того, любая помощь будет принята с благодарностью.

Ответы [ 2 ]

1 голос
/ 15 марта 2019

Сначала обратите внимание на пару вещей.

  • primaryCustomer[a][b] = primaryCustomer[b][a] потому что вы используете метрику расстояния. Это означает, что диапазоны на ваших двух циклах for могут быть сброшены:
    numCustomers = 51
    primaryCustomer = np.zeros(shape = (numCustomers, numCustomers))
    for customerA in range(numCustomers-1):
        for customerB in range(customerA+1, numCustomers):
            primaryCustomer[customerA][customerB] = dist(customerA,customerB)
    primaryCustomer += np.transpose(primaryCustomer)

Примечание * вы можете изменить секунду для диапазона цикла, чтобы он также начинался с 0, чтобы сохранить исходную структуру цикла, но тогда вам нужно будет удалить линию транспонирования. Вы также можете иметь primaryCustomer[a][b] = primaryCustomer[b][a] = dist(a,b) если вы не хотите использовать транспозицию, но все равно избегаете ненужных вычислений.

  • primaryCustomer = np.zeros(shape = (50,50)) Я предполагаю, что предназначен для хранения расстояния между двумя клиентами. Тем не менее, похоже, у вас есть 51 клиентов, а не 50?
  • Вам следует подумать о расчете расстояний в более общем виде. то есть как вы могли бы сделать расчет расстояния независимым от размера списка?
  • Почему вы создаете исходный двумерный массив 0 для сохранения расстояния, а затем добавляете его? Создание списка thisCustomer не кажется необходимым, и фактически решение, опубликованное Reedinationer, инициализирует его, но никогда даже не использует его. Кроме того, как кто-то сказал alreadyd, это не так, как работает np.append. Лучше всего изменить матрицу расстояний, которую вы изначально создали напрямую.
  • Почему primaryCustomer[a][a] = 999? Разве расстояние между списком и самим собой не должно быть 0? Если вы действительно хотите, чтобы оно было 999, я советую вам выяснить, как изменить приведенный выше блок кода, чтобы учесть это.
1 голос
/ 15 марта 2019

Я думаю это то, что вы собираетесь, но поправьте меня, если я ошибаюсь:

import numpy as np
from random import randint

Customer = [[0, 0, 0, 0, 0] for i in range(51)]

for n in range(51):
    Customer[n] = np.ones(5)
    Customer[n][randint(2, 4):5] = 0
    np.random.shuffle(Customer[n])

primaryCustomer = np.zeros(shape=(50, 50))

for customer in range(0, 50):
    thisCustomer = [0 for i in range(51)]
    for pair in range(0, 50):
        if customer == pair:
            primaryCustomer[customer][pair] = 999
        else:
            calculateScores = (((Customer[customer][0] - Customer[pair][0]) ** 2
                                  + (Customer[customer][1] - Customer[pair][1]) ** 2
                                  + (Customer[customer][2] - Customer[pair][2]) ** 2
                                  + (Customer[customer][3] - Customer[pair][3]) ** 2
                                  + (Customer[customer][4] - Customer[pair][4]) ** 2) ** 0.5)
            primaryCustomer[customer][pair] = calculateScores

print(primaryCustomer)

Я думаю, что основной проблемой, которую я нашел с вашими петлями, было местоположениеиз thisCustomer = [0 for i in range(51)], я думаю, вы хотели поднять его еще на один уровень, как у меня.Однако я не вижу необходимости в этой строке и изменил thisCustomer[pair] для прямой записи в primaryCustomer[customer][pair], что исключает необходимость в thisCustomer = [0 for i in range(51)] каждом цикле, что ускорит вашу программу и улучшит использование памяти, если взять строкуполностью.

Пример вывода:

[[999.2.23606798 1. ... 2. 0. 1.73205081] [2.23606798 999. 2. ... 1. 2.23606798 1.41421356] [1. 2. 999. ... 1.73205081 1. 2.] ... [2. 1.1.73205081 ... 999. 2. 1.73205081] [0. 2.23606798 1. ... 2. 999. 1.73205081] [1.73205081 1.41421356 2. ... 1.73205081 1.73205081 999.]]

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