Применение функции ко всему пространству параметров / 2d массиву, Numpy - PullRequest
1 голос
/ 18 июня 2020

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

Я хочу иметь 2-мерный массив или пространство параметров. Все значения от 1200 до 1800 и все их комбинации. Итак, [1200, 1200], [1200, 1201], [1200, 1202] .... [1201, 1200], [1201, 1201] и т.д. c.

Я хочу применить функцию по всему этому пространству параметров. Функция использует еще 2 массива, которые также являются значениями в диапазоне 1200-1800. Но это случайные значения, поэтому эти 2 дополнительных массива представляют собой случайные значения в диапазоне 1200-1800, так что [1356, 1689, 1436, ...] и [1768, 1495, 1358, ...] и c. check_array1 и check_array2.

Функция должна перемещаться по пространству параметров, проверяя условие, которое в основном if x < check_array1 and y < check_array2 then 1 else 0. Где x и y - каждая из указанных c точек в 2-м пространстве параметров. Ему необходимо проверить каждую комбинацию значений в проверочных массивах. Суммируйте сумму, сравните с другим значением c и верните разницу.

Каждая уникальная комбинация в сетке пространства параметров будет иметь уникальное значение, связанное с ней, в зависимости от того, как эти параметры c Значения x и y из пространства параметров сравниваются с двумя контрольными массивами.

Надеюсь, что это делает, я просто не могу понять, как превратить это в Numpy дружественную проблему. Извините за стену текста.

Изменить: я написал его на более базовом c Python, чтобы лучше проиллюстрировать то, что я пытаюсь сделать.

check1 = np.random.randint(1200, 1801, 300)
check2 = np.random.randint(1200, 1801, 300)

def check_this_double(i, j, check1, check2):
   total = 0
   for num in range(0, len(check1)):
       if ((i < check1[num]) or (j < check2[num])):
           total += 1           
   return total

outputs = {}
for i in range(1200, 1801):
   for j in range(1200, 1801):
    outputs[i,j] = check_this_double(i, j, check1, check2)

Изменить 2: Я верю, что у меня это есть. Следуя коду Горы, создавая p_space, а затем используя np.vectorize в обычном Python fuction.

check1 = np.random.randint(1200, 1801, 300)
check2 = np.random.randint(1200, 1801, 300)

def calc(i, j):    
   total = np.where(np.logical_or(check1 < i, checks2 < j), 1, 0)
   return total.sum()

rate_calv_v = np.vectorize(rate_calc)

final = rate_calv_v(p_space[:, 0], p_space[:, 1])

Похоже на читерство :), должен быть способ сделать это без np.vectorize. Но мне кажется, это работает.

1 Ответ

0 голосов
/ 18 июня 2020

Я не совсем понимаю проблему, которую вы пытаетесь решить. Я надеюсь, что следующее даст вам отправную точку в том, как можно использовать numpy. Я рекомендую пройти вводное руководство numpy.

numpy логическая индексация и векторная математика могут улучшить скорость и уменьшить потребность в циклах. Вот мое понимание первой части ваших вопросов.

import numpy as np

xv, yv = np.meshgrid(np.arange(1200, 1801), np.arange(1200, 1801))
p_space = np.stack((xv, yv), axis=-1)  # the 2d array described

# print original values
print(p_space[0,:10,0])
print(p_space[0,-10:,0])

old_shape = p_space.shape
p_space = p_space.reshape(-1, 2)  # flatten the array for the compare

check1 = np.random.randint(1200, 1801, len(p_space))
check2 = np.random.randint(1200, 1801, len(p_space))

# you can used this to access and modify values that meet the condition
index_array = np.logical_and(p_space[:, 0] < check1, p_space[:, 1] < check2)

# do some sort of complex math
p_space[index_array] = p_space[index_array] / 2 + 10

# get the sum across the two columns
print(np.sum(p_space, axis=0))

p_space = p_space.reshape(old_shape)  # return to the grid shape

# print modified values
print(p_space[0,:10,0])  # likely to be changed based on checks
print(p_space[0,-10:,0])  # unlikely to be changed
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...