Если порядок в выходном массиве не имеет значения, то, вероятно, вы можете просто использовать ответ Eelco Hoogendoorn .Однако, если вы хотите сохранить тот же относительный порядок, что и в исходном массиве, вот еще один возможный подход.
import numpy as np
a = np.array([
[1, 0, 1, 0],
[0, 0, 1, 1],
[1, 0, 1, 0],
[0, 0, 1, 1],
[1, 1, 1, 0],
[1, 1, 1, 0],
[1, 1, 1, 0],
[1, 1, 1, 0],
])
idx = np.array([0, 2, 3, 4, 6, 7])
# Make an array of row numbers
r = np.arange(len(a))
# Replace row numbers in idx with -1
# (use assume_unique only if indices in idx are unique)
r[np.isin(r, idx, assume_unique=True)] = -1
# Add the column to the array
a2 = np.concatenate([a, r[:, np.newaxis]], axis=-1)
# Find unique indices and inverse indices
_, uniq_idx, inv_idx = np.unique(a2, return_index=True, return_inverse=True, axis=0)
# Sort indices to make output array and inverse indices
s = np.argsort(uniq_idx)
a_uniq = a[uniq_idx[s]]
inv_idx = s[inv_idx]
print(a_uniq)
# [[1 0 1 0]
# [0 0 1 1]
# [0 0 1 1]
# [1 1 1 0]
# [1 1 1 0]]
print(np.all(a_uniq[inv_idx] == a))
# True
РЕДАКТИРОВАТЬ: Некоторое дальнейшее объяснение.
Идея в решении вышеприменяется np.unique
, но таким образом, что строки, не включенные в idx
, не затрагиваются этим.Чтобы сделать это, вы можете просто добавить новый номер в каждую строку.Для строк, включенных в idx
, это число всегда будет -1
, а для остальных строк это будет разное число для каждого.Таким образом, невозможно, чтобы строки, не входящие в idx
, были удалены с помощью np.unique
.Для этого я строю r
, сначала с np.arange(len(a))
, что дает вам число в строке:
[0 1 2 3 4 5 6 7]
Затем я проверяю, какие из них находятся в idx
с np.isin(r, idx, assume_unique=True)
(assume_unique
можно использовать только в том случае, если элементы в idx
гарантированно являются уникальными), поэтому r[np.isin(r, idx, assume_unique=True)] = -1
превратит все индексы idx
в -1:
[-1 1 -1 -1 -1 5 -1 -1]
, которые добавляются как новыестолбец в a
в a2
:
[[ 1 0 1 0 -1]
[ 0 0 1 1 1]
[ 1 0 1 0 -1]
[ 0 0 1 1 -1]
[ 1 1 1 0 -1]
[ 1 1 1 0 5]
[ 1 1 1 0 -1]
[ 1 1 1 0 -1]]
Теперь нужно просто применить np.unique
к a2
.Как и ожидалось, только строки в idx
могут быть удалены.Однако, поскольку мы хотим сохранить исходный относительный порядок, мы не можем использовать вывод np.unique
, потому что он отсортирован.Мы используем return_index
и return_inverse
, чтобы получить индексы, которые составляют массив уникальных строк, и индексы, которые возвращают вас к исходному массиву, и фактически отбрасывают новый массив.
Для формирования окончательного массиваВам нужно отсортировать uniq_idx
, чтобы сохранить относительный порядок, а затем inv_idx
соответственно.np.argsort
дает вам индексы, которые сортируют uniq_idx
в s
.uniq_idx[s]
- это просто отсортированный массив уникальных индексов строк, а s[inv_idx]
отобразит каждый обратный индекс в inv_idx
на соответствующий индекс в массиве, который был восстановлен.Итак, наконец, a[uniq_idx[s]]
дает вам выходной массив, а новый inv_idx
возвращает вас к исходному.