2015-12-06 4 views
0

Я нашел другие методы, такие как this, для удаления повторяющихся элементов из массива. Мое требование несколько другое. Если я начну с:Поиск индексов неповторимых элементов в массиве Numpy

array([[1, 2, 3], 
     [2, 3, 4], 
     [1, 2, 3], 
     [3, 2, 1], 
     [3, 4, 5]]) 

Я хотел бы закончить с:

array([[2, 3, 4], 
     [3, 2, 1] 
     [3, 4, 5]]) 

Вот что я бы в конечном счете, хотел бы в конечном итоге с, но есть дополнительное требование. Я также хотел бы сохранить либо массив индексов, чтобы отменить, либо сохранить (a la numpy.take).

Я использую Numpy 1.8.1

+0

Вы можете подсчитать, сколько раз каждая строка появляется с помощью методов, предложенных, например, [ здесь] (http://stackoverflow.com/q/27000092/3923281) и [здесь] (http://stackoverflow.com/q/33786245/3923281). Я думаю, что именно здесь сводится ваша проблема. –

+0

@ajcr Я не могу использовать 'return_counts', поэтому # 1 для меня. К сожалению, для # 2 требуется отсортированный массив, и мне нужно сохранить порядок. – codedog

+0

@codedog Были ли ответы полезными? Если нет, не могли бы вы сообщить нам, что еще вы ищете, – imp9

ответ

0

Мы хотим, чтобы найти строки, которые не дублируются в массиве, сохраняя при этом порядок.

Я использую это solution, чтобы объединить каждую строку a в один элемент, чтобы мы могли найти уникальные строки, используя np.unique(,return_index=True, return_inverse= True). Затем я изменил это значение function, чтобы вывести счетчики уникальных строк, используя индекс и инверсию. Оттуда я могу выбрать все уникальные строки, которые имеют counts == 1.

a = np.array([[1, 2, 3], 
     [2, 3, 4], 
     [1, 2, 3], 
     [3, 2, 1], 
     [3, 4, 5]]) 

#use a flexible data type, np.void, to combine the columns of `a` 
#size of np.void is the number of bytes for an element in `a` multiplied by number of columns 
b = a.view(np.dtype((np.void, a.dtype.itemsize * a.shape[1]))) 
_, index, inv = np.unique(b, return_index = True, return_inverse = True) 

def return_counts(index, inv): 
    count = np.zeros(len(index), np.int) 
    np.add.at(count, inv, 1) 
    return count 

counts = return_counts(index, inv) 

#if you want the indices to discard replace with: counts[i] > 1 
index_keep = [i for i, j in enumerate(index) if counts[i] == 1] 

>>>a[index_keep] 
array([[2, 3, 4], 
    [3, 2, 1], 
    [3, 4, 5]]) 

#if you don't need the indices and just want the array returned while preserving the order 
a_unique = np.vstack(a[idx] for i, idx in enumerate(index) if counts[i] == 1]) 
>>>a_unique 
array([[2, 3, 4], 
    [3, 2, 1], 
    [3, 4, 5]]) 

Для np.version> = 1,9

b = a.view(np.dtype((np.void, a.dtype.itemsize * a.shape[1]))) 
_, index, counts = np.unique(b, return_index = True, return_counts = True) 

index_keep = [i for i, j in enumerate(index) if counts[i] == 1] 
>>>a[index_keep] 
array([[2, 3, 4], 
    [3, 2, 1], 
    [3, 4, 5]]) 
+0

кроме запроса было исключить [1,2,3], поскольку он встречается более одного раза. –

+0

@ Dan Patterson Спасибо, что указали это, я отредактировал мой решение. – imp9

+0

Вчера я узнал, что мы реализовали это в расширении C. Я не тестировал это решение явно, но он очень похож на то, что было реализовано здесь. Вот почему я принял это решение. Благодарю. – codedog

0

Если вы хотите удалить все экземпляры элементов, что существует в дублированных версиях, вы можете перебирать массив, найти индексы существующих элементов в более чем одной версии, и, наконец, удалить эти:

# The array to check: 
array = numpy.array([[1, 2, 3], 
     [2, 3, 4], 
     [1, 2, 3], 
     [3, 2, 1], 
     [3, 4, 5]]) 

# List that contains the indices of duplicates (which should be deleted) 
deleteIndices = [] 

for i in range(0,len(array)): # Loop through entire array 
    indices = range(0,len(array)) # All indices in array 
    del indices[i] # All indices in array, except the i'th element currently being checked 

for j in indexes: # Loop through every other element in array, except the i'th element, currently being checked 
    if(array[i] == array[j]).all(): # Check if element being checked is equal to the j'th element 
     deleteIndices.append(j) # If i'th and j'th element are equal, j is appended to deleteIndices[] 

# Sort deleteIndices in ascending order: 
deleteIndices.sort() 

# Delete duplicates 
array = numpy.delete(array,deleteIndices,axis=0) 

Воспроизводит:

>>> array 
array([[2, 3, 4], 
     [3, 2, 1], 
     [3, 4, 5]]) 

>>> deleteIndices 
[0, 2] 

Как вы оба удаляете дубликаты и получаете список индексов, которые нужно отменить.

0

numpy_indexed пакет (отказ от ответственности: Я его автор) может быть использован для решения таких проблем в векторизованного образом:

index = npi.as_index(arr) 
keep = index.count == 1 
discard = np.invert(keep) 
print(index.unique[keep]) 
Смежные вопросы