Учитывая следующий 2D numpy массив M, сформируйте два набора и массива A и B, содержащие элементы M, такие, что набор A и набор B не содержат общего элемента. Другими словами, разбейте M на два набора строк из M, чтобы они охватывали непересекающиеся наборы чисел. Алгоритм должен работать для любого числа наборов.
Дано:
import numpy as np
M =
[[ 2 1 0]
[ 0 3 2]
[ 1 4 0]
[ 0 4 3]
[ 5 1 2]
[ 3 5 2]
[ 5 4 1]
[ 4 5 3]
[ 8 7 6]
[ 6 9 8]
[ 7 10 6]
[ 6 10 9]
[11 7 8]
[ 9 11 8]
[11 10 7]
[10 11 9]]
Возврат:
setA = {0, 1, 2, 3, 4, 5}
setB = {6, 7, 8, 9, 10, 11}
A =
[[ 2 1 0]
[ 0 3 2]
[ 1 4 0]
[ 0 4 3]
[ 5 1 2]
[ 3 5 2]
[ 5 4 1]
[ 4 5 3]]
B =
[[ 8 7 6]
[ 6 9 8]
[ 7 10 6]
[ 6 10 9]
[11 7 8]
[ 9 11 8]
[11 10 7]
[10 11 9]]
Мне удалось сформировать обе матрицы A и B ( наборы не являются строго необходимыми), но мой код кажется не элегантным, и мне интересно, есть ли лучший способ. У меня также есть ощущение, что может произойти сбой, если элементы M выйдут из строя.
Редактировать: Исправление: Мой код работает для этого примера, но не для других.
Мое решение:
objects = []
obj = []
i = 0
for idx, face in enumerate(M):
if i == 0:
obj.append(face)
i = i + 1
else:
if np.isin(face,obj).any():
obj.append(face)
else:
objects.append(obj.copy())
obj = []
obj.append(face)
i = 0
if idx == len(M)-1:
objects.append(obj.copy())
print(np.array(objects[0]),'\n\n',np.array(objects[1]))
# returns
[[2 1 0]
[0 3 2]
[1 4 0]
[0 4 3]
[5 1 2]
[3 5 2]
[5 4 1]
[4 5 3]]
[[ 8 7 6]
[ 6 9 8]
[ 7 10 6]
[ 6 10 9]
[11 7 8]
[ 9 11 8]
[11 10 7]
[10 11 9]]
Примечание: я помечаю networkx, потому что мне любопытно, есть ли решение через него. Я использовал это в другом месте в моем коде, и это значительно ускорило все.
Если любопытно: это относится к проблеме, которую я ломал голову над . Каждый элемент в M представляет собой tri angular face
, где каждый элемент face
является вершиной треугольника. В М есть два полных объекта. А и Б не связаны. Вышеприведенный алгоритм является способом сортировки M для объектов A и B.