2015-11-14 3 views
0

Я очень сильно застрял, и каждая запрошенная мной питонистика не может помочь.Сравнение векторов в массиве векторов

Я использую vstack, чтобы создать массив векторов в цикле, как это:

Corr = np.vstack((Corr, S)) 

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

Я знаю, что это сравнение может быть сделано в списках, но я не нашел способ добавить полные векторы в список.

Это результат (я пометил уникальные векторы с уникальными буквами):

Corr = [[ 0. 0. 0. 0. -2. 4. 4. 2. 2.] #a 
[-4. -4. -4. -4. 2. 4. 4. 2. 2.]#b 
[-4. 0. 0. 4. -2. 0. 0. -2. 2.]#c 
[ 0. -4. -4. 0. 2. 0. 0. -2. 2.]#d 
[ 0. -4. 4. 0. -2. 0. 0. 2. -2.]#e 
[-4. 0. 0. -4. 2. 0. 0. 2. -2.]#f 
[-4. -4. 4. 4. -2. 4. -4. -2. -2.]#g 
[ 0. 0. 0. 0. 2. 4. -4. -2. -2.]#h 
[ 0. 4. -4. 0. -2. 0. 0. 2. -2.]#i 
[-4. 0. 0. -4. 2. 0. 0. 2. -2.]#f 
[-4. 4. -4. 4. -2. -4. 4. -2. -2.]#j 
[ 0. 0. 0. 0. 2. -4. 4. -2. -2.]#k 
[ 0. 0. 0. 0. -2. -4. -4. 2. 2.]#l 
[-4. 4. 4. -4. 2. -4. -4. 2. 2.]#m 
[-4. 0. 0. 4. -2. 0. 0. -2. 2.]#n 
[ 0. 4. 4. 0. 2. 0. 0. -2. 2.]#o 
[ 4. 0. 0. -4. -2. 0. 0. -2. 2.]#c 
[ 0. -4. -4. 0. 2. 0. 0. -2. 2.]#d 
[ 0. 0. 0. 0. -2. -4. -4. 2. 2.]#p 
[ 4. -4. -4. 4. 2. -4. -4. 2. 2.]#q 
[ 4. -4. 4. -4. -2. -4. 4. -2. -2.]#r 
[ 0. 0. 0. 0. 2. -4. 4. -2. -2.]#k 
[ 0. -4. 4. 0. -2. 0. 0. 2. -2.]#e 
[ 4. 0. 0. 4. 2. 0. 0. 2. -2.]#s 
[ 4. 4. -4. -4. -2. 4. -4. -2. -2.]#t 
[ 0. 0. 0. 0. 2. 4. -4. -2. -2.]#h 
[ 0. 4. -4. 0. -2. 0. 0. 2. -2.]#i 
[ 4. 0. 0. 4. 2. 0. 0. 2. -2.]#s 
[ 4. 0. 0. -4. -2. 0. 0. -2. 2.]#u 
[ 0. 4. 4. 0. 2. 0. 0. -2. 2.]#o 
[ 0. 0. 0. 0. -2. 4. 4. 2. 2.]]#a 

Я не знаю, почему vstack добавляет период вместо запятой (в петлях каждый вектор S имеет запятая, когда я печатаю ее отдельно!).

Мне нужен конечный результат, чтобы быть массивом уникальных векторов (так что в этом случае это будут векторы a-u, то есть 21 вектор).

+1

Как побочное примечание, вызов vstack в цикле для создания матрицы один за другим - это плохая практика. Вместо этого создайте обычный старый список всех ваших векторов, а затем объедините их все сразу. Это уменьшает количество копий, если число векторов велико. –

+0

John, ссылка «Найти уникальные строки», о которой вы упомянули, также имеет ряд решений vstack. И векторные элементы разделены комментариями. Я использую vstack и появляются периоды. Невозможно использовать любой из этих методов для сортировки по массиву. – user3625380

+0

«Периоды, показывающие», не являются проблемой, они нормальные. Они показывают, что ваши номера - это float, а не ints. В списке Python он по умолчанию печатает запятыми между элементами. Точки-vs-запятые не влияют на то, какие данные внутри, это всего лишь дисплей. –

ответ

2

Если вы конвертируете свои векторы в кортежи, вы можете поместить их в set, который автоматически удалит дубликаты. Например:

unique_vectors = set(map(tuple, Corr)) 

array_of_unique_vectors = np.array(list(unique_vectors)) 

Edit: мне было интересно, поэтому я быстро протестировали три предложенных решений здесь. Результаты совпадают с порядком возвращаемых элементов, и оказывается, что метод Pandas drop_duplicates превосходит другие.

import numpy as np 
import pandas as pd 

def unique_set(a): 
    return np.vstack(set(map(tuple, a))) 

def unique_numpy(a): 
    a = np.ascontiguousarray(a) 
    view = a.view(np.dtype(('void', a.itemsize * a.shape[1]))) 
    unique = np.unique(view) 
    return unique.view(a.dtype).reshape(-1, a.shape[1]) 

def unique_pandas(a): 
    return pd.DataFrame(a).drop_duplicates().values 

a = np.random.randint(0, 5, (100000, 5)) 

%timeit unique_set(a) 
10 loops, best of 3: 183 ms per loop 

%timeit unique_numpy(a) 
10 loops, best of 3: 43.1 ms per loop 

%timeit unique_pandas(a) 
100 loops, best of 3: 10.3 ms per loop 
+0

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

+0

На самом деле, я думаю, что это довольно близко к оптимальному. Вы хотите, чтобы хэш-таблица выполняла сравнение новых векторов в O [1], а '' set() '- самый простой способ создать хеш-таблицу для устранения конфликтов.В Python 3 '' map() '' является генератором, поэтому вы также не столкнетесь с огромными проблемами с памятью. В Python 2 '' itertools.imap'' было бы лучше. – jakevdp

+0

Вы обычный пользователь NumPy? Вы знакомы с тем, как это работает и почему люди его используют? –

2

Вот ответ, который позволяет избежать дублирования данных и не требует внешних пакетов, таких как панда:

Corr = np.ascontiguousarray(Corr) 
view = Corr.view(np.dtype(('void', Corr.itemsize * Corr.shape[1]))) 
unique_view = np.unique(view) 
unique = unique_view.view(Corr.dtype).reshape(-1, Corr.shape[1]) 

Я нахожу его примерно в 5 раз быстрее, чем предлагаемое ранее решение набора кортежей.

Смежные вопросы