У меня есть три массива, a
, b
и c
. Формы (N, 2)
, (N, 3)
, (N, 3)
соответственно.
Мне нужно сравнить элементы в строке в b
и обновить индекс в той же строке в a
. Я думал, что понял, как векторизовать этот метод, но я думаю, что мои измерения неверны.
То, что у меня сейчас есть:
def to_cube(points):
cube = np.empty((len(points), 3), dtype=np.half)
delta = np.empty_like(cube)
q = ((2 / 3) * points[:, 0]) / 0.1
r = (((-1 / 3) * points[:, 0]) + ((np.sqrt(3) / 3) * points[:, 1])) / 0.1
cube[:, 0] = np.round(q)
cube[:, 1] = np.round(-q-r)
cube[:, 2] = np.round(r)
delta[:, 0] = np.abs(cube[:, 0] - q)
delta[:, 1] = np.abs(cube[:, 1] - (-q-r))
delta[:, 2] = np.abs(cube[:, 2] - r)
if delta[:, 0] > delta[:, 1] and delta[:, 1] > delta[:, 2]:
cube[:, 0] = -cube[:, 1] - cube[:, 2]
elif delta[:, 1] > delta[:, 2]:
cube[:, 1] = -cube[:, 0] - cube[:, 2]
else:
cube[:, 2] = -cube[:, 0] - cube[:, 1]
return cube
Это бросает ValueError: The truth value of an array with more than one element is ambiguous
.
Изучив условные выражения, становится ясно, что первая проверка delta[:, 0] > delta[:, 1]
вернет массив формы (N, 1)
. Как изменить это значение на go для каждой строки в a
, получить соответствующие индексы в этой строке, а затем обновить эту же строку в b
для указанного c индекса, основанного на условных выражениях?
Редактировать: образец
В этом примере предполагается, что q
и r
выполнены. Эти матрицы представляют cube
и delta
:
>>> cube
array([[275.0, -400.0, 124.0]], dtype=float16) # so this is a (1, 3) but could be (N, 3)
>>> cube[0]
array([275.0, -400.0, 124.0], dtype=float16)
>>> delta
array([[5., 10., 3.]], dtype=float16)
>>> delta[0]
array([5., 10., 3.], dtype=float16)
Теперь выполняются через условные выражения (значения подчинены):
if 5.0 > 10.0 and 10.0 > 3.0:
cube[0] = -(-400.0) - 124.0
elif 10.0 > 3.0:
cube[1] = -(275.0) - 124.0
else:
cube[2] = -(275.0) - (-400.0)
return cube # array([275.0, -(275.0) - 124.0, 124.0], dtype=float16)
Это показывает, что происходит в строке, теперь мне нужно сделать это для всех строк.
Редактировать: потенциальное решение (оно векторизовано?)
Существует способ обеспечить независимый доступ к строкам, используя a for-range
:
def to_cube(points):
cube = np.empty((len(points), 3), dtype=np.half)
delta = np.empty_like(cube)
q = ((2 / 3) * points[:, 0]) / 0.1
r = (((-1 / 3) * points[:, 0]) + ((np.sqrt(3) / 3) * points[:, 1])) / 0.1
cube[:, 0] = np.round(q)
cube[:, 1] = np.round(-q-r)
cube[:, 2] = np.round(r)
delta[:, 0] = np.abs(cube[:, 0] - q)
delta[:, 1] = np.abs(cube[:, 1] - (-q-r))
delta[:, 2] = np.abs(cube[:, 2] - r)
for i in range(len(cube)):
if delta[i, 0] > delta[i, 1] and delta[i, 1] > delta[i, 2]:
cube[i, 0] = -cube[i, 1] - cube[i, 2]
elif delta[i, 1] > delta[i, 2]:
cube[i, 1] = -cube[i, 0] - cube[i, 2]
else:
cube[i, 2] = -cube[i, 0] - cube[i, 1]
return cube
Тем не менее, я сейчас "зацикливаюсь" над массивами, не похоже на векторизацию или трансляцию.