Получение индексов для повторяющихся столбцов массива numpy

У меня есть массив numpy с повторяющимися столбцами:

import numpy as np
A = np.array([[1, 1, 1, 0, 1, 1], [1, 2, 2, 0, 1, 2], [1, 3, 3, 0, 1, 3]])

Мне нужно найти индексы для этих дубликатов или что-то вроде этого:

[0, 4]

[1, 2, 5]

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

Спасибо

Я попытался сначала идентифицировать уникальные столбцы с помощью этой функции:

def unique_columns(data): ind = np.lexsort(data) return data.T[ind[np.concatenate(([True], any(data.T[ind[1:]]!=data.T[ind[:-1]], axis=1)))]].T

Но я не могу определить индексы оттуда.

2 ответа

К сожалению, нет простого способа сделать это. Использование ответа np.unique. Этот метод требует, чтобы ось, которую вы хотите уникальны, была непрерывной в памяти, а типичный формат памяти numpy C смежный или непрерывный по строкам. К счастью, numpy делает это преобразование простым:

A = np.array([[1, 1, 1, 0, 1, 1], [1, 2, 2, 0, 1, 2], [1, 3, 3, 0, 1, 3]])
def unique_columns2(data): dt = np.dtype((np.void, data.dtype.itemsize * data.shape[0])) dataf = np.asfortranarray(data).view(dt) u,**** = np.unique(dataf, return_inverse=True) u = u.view(data.dtype).reshape(-1,data.shape[0]).T return (u,****)

Наш результат:

u,**** = unique_columns2(A)
u
array([[0, 1, 1], [0, 1, 2], [0, 1, 3]])
****
array([1, 2, 2, 0, 1, 2])

Я не совсем уверен, что вы хотите сделать отсюда, например, вы можете сделать что-то вроде этого:

>>> [np.where(****==x)[0] for x in range(u.shape[0])]
[array([3]), array([0, 4]), array([1, 2, 5])]

Некоторые тайминги:

tmp = np.random.randint(0,4,(30000,500))
#BiRico and OP answer
%timeit unique_columns(tmp)
1 loops, best of 3: 2.91 s per loop
%timeit unique_columns2(tmp)
1 loops, best of 3: 208 ms per loop


Вот краткое описание того, как подойти к нему. Используйте numpy.lexsort для сортировки столбцов, таким образом все дубликаты будут сгруппированы вместе. Когда дубликаты объединены, вы можете легко определить, какие столбцы являются дубликатами, и индексы, соответствующие этим столбцам.

Здесь реализована реализация описанного выше метода.

import numpy as np
def duplicate_columns(data, minoccur=2): ind = np.lexsort(data) diff = np.any(data.T[ind[1:]] != data.T[ind[:-1]], axis=1) edges = np.where(diff)[0] + 1 result = np.split(ind, edges) result = [group for group in result if len(group) >= minoccur] return result
A = np.array([[1, 1, 1, 0, 1, 1], [1, 2, 2, 0, 1, 2], [1, 3, 3, 0, 1, 3]])
print(duplicate_columns(A))
# [array([0, 4]), array([1, 2, 5])]

licensed under cc by-sa 3.0 with attribution.