Я пытаюсь обновить несколько столбцов набора строк одновременно. (в моем случае у меня одинаковое количество столбцов и количество строк - я делаю матрицу подобия, но, вообще говоря, это не должно быть важно). Есть ли способ сделать это более эффективно, чем мои примеры ниже? - Я открыт для использования python lists
, pandas
или numpy
; не имеет большого значения; до тех пор, пока он самый быстрый.
Пример 1 - Два вложенные for
петель
adj_mat = np.array([[1,1,1,0,0,0,0,0,0],
[1,1,1,0,0,0,0,0,0],
[1,1,1,1,0,0,0,0,0],
[0,0,1,1,1,1,0,0,0],
[0,0,0,1,1,1,0,0,0],
[0,0,0,1,1,1,1,0,0],
[0,0,0,0,0,1,1,1,1],
[0,0,0,0,0,0,1,1,1],
[0,0,0,0,0,0,1,1,1]])
inlier_mask = np.array([False, False, False, True, True, True, False,
False, False])
inlier_idx = np.array(np.nonzero(inlier_mask))[0].tolist()
for i in inlier_idx:
for j in inlier_idx:
adj_mat[i,j] += 1
print(adj_mat)
Выход:
[[1 1 1 0 0 0 0 0 0]
[1 1 1 0 0 0 0 0 0]
[1 1 1 1 0 0 0 0 0]
[0 0 1 2 2 2 0 0 0]
[0 0 0 2 2 2 0 0 0]
[0 0 0 2 2 2 1 0 0]
[0 0 0 0 0 1 1 1 1]
[0 0 0 0 0 0 1 1 1]
[0 0 0 0 0 0 1 1 1]]
Пример 2 - Только один for
цикла
adj_mat = np.array([[1,1,1,0,0,0,0,0,0],
[1,1,1,0,0,0,0,0,0],
[1,1,1,1,0,0,0,0,0],
[0,0,1,1,1,1,0,0,0],
[0,0,0,1,1,1,0,0,0],
[0,0,0,1,1,1,1,0,0],
[0,0,0,0,0,1,1,1,1],
[0,0,0,0,0,0,1,1,1],
[0,0,0,0,0,0,1,1,1]])
inlier_mask = np.array([False, False, False, True, True, True, False,
False, False])
inlier_idx = np.array(np.nonzero(inlier_mask))[0].tolist()
for i in inlier_idx:
adj_mat[i,inlier_idx] += 1
Выход:
[[1 1 1 0 0 0 0 0 0]
[1 1 1 0 0 0 0 0 0]
[1 1 1 1 0 0 0 0 0]
[0 0 1 2 2 2 0 0 0]
[0 0 0 2 2 2 0 0 0]
[0 0 0 2 2 2 1 0 0]
[0 0 0 0 0 1 1 1 1]
[0 0 0 0 0 0 1 1 1]
[0 0 0 0 0 0 1 1 1]]
Есть ли решение, такое как: adj_mat[inlier_idx,inlier_idx] += 1
который может достичь этого без циклов?
Используйте np.ix_
для создания двух широковещательных массивов индексирования, а затем проиндексируйте и добавьте -
adj_mat[np.ix_(inlier_idx, inlier_idx)] += 1
# or adj_mat[np.ix_(inlier_mask, inlier_mask)] += 1
Кроме того, мы можем вручную создавать broadcastable
массивы с расширением inlier_idx
до 2D
с помощью None/np.newaxis
-
inlier_idx = np.flatnonzero(inlier_mask)
adj_mat[inlier_idx[:,None], inlier_idx] += 1