2014-08-29 4 views
2

У меня есть большой массив, часть которого выглядит как этотКак вернуть повторяющийся элемент из массива только один раз?

... 
[u'3767' u'SS14 3HG'] 
[u'3768' u'SS14 3HG'] 
[u'3769' u'SS14 3HG'] 
[u'3770' u'SS14 3HG'] 
[u'3771' u'SS14 3HG'] 
[u'3772' u'SS14 3HG'] 
[u'4300' u'TA1 4DY'] 
[u'4301' u'TA1 4DY'] 
[u'4302' u'TA1 4DY'] 
[u'4303' u'TA1 4DY'] 
[u'4304' u'TA1 4DY'] 
... 

Как вы можете видеть детали в несколько раз второго столбца повторов. Мне нужно иметь возможность получить только один экземпляр каждого повторяющегося элемента и его соответствующего номера (из 1-го столбца). Например:

#output 
[u'3767' u'SS14 3HG'] 
[u'4300' u'TA1 4DY'] 

Первоначально я думал, что я мог бы создать for цикл, который проверяет, является ли текущий элемент такой же, как другой, и если да, то вернуть товар и удалите следующий. Тем не менее,

а) Я хотел бы получить «индекс вне границ» ошибки и

б) не было бы это очень дорого?

Любые идеи?

+0

'u'SS14 3HG'' имеет несколько номеров: вы хотите отобразить только один или все из них? – 2014-08-29 09:19:12

+0

@Begueradj Я думаю, вы неправильно поняли; по соответствующим номерам я имел в виду номера в 1-м столбце, которые находятся в той же строке, что и элемент во втором столбце – Petar

+0

Да, я знаю, но в первом столбце имеется несколько соответствующих номеров для 'u'SS14 3HG'': так вы хотите перечислить их всех или только один из них случайным образом? – 2014-08-29 09:22:30

ответ

2

Вы можете использовать np.unique получить индексы первых появлений записей во втором столбце вашего массива:

>>> indexes = np.unique(myarr[:,1], return_index=True) 
(array([u'SS14 3HG', u'TA1 4DY'], 
    dtype='<U8'), array([0, 6])) 

Это возвращает кортеж: массив уникальных записей myarr и массив индексов первого вхождения этой записи.

Вы можете вернуть соответствующие строки из myarr с помощью этих индексов:

>>> myarr[indexes[1]] 
array([[u'3767', u'SS14 3HG'], 
     [u'4300', u'TA1 4DY']], 
     dtype='<U8') 
+0

Как я об этом не думал! Отлично, спасибо. – Petar

+0

Нет проблем, рад, что ответ был вам полезен. –

2

Если они уже сгруппированы вместе нравится, что вы можете использовать itertools.groupby

from itertools import groupby 
[next(v) for g,v in groupby(your_list, lambda x:x[1])] 

например:

>>> your_list = [[u'3767', 'SS14 3HG'], 
... [u'3768', 'SS14 3HG'], 
... [u'3769', 'SS14 3HG'], 
... [u'3770', 'SS14 3HG'], 
... [u'3771', 'SS14 3HG'], 
... [u'3772', 'SS14 3HG'], 
... [u'4300', 'TA1 4DY'], 
... [u'4301', 'TA1 4DY'], 
... [u'4302', 'TA1 4DY'], 
... [u'4303', 'TA1 4DY'], 
... [u'4304', 'TA1 4DY']] 
>>> from itertools import groupby 
>>> [next(v) for g,v in groupby(your_list, lambda x:x[1])] 
[[u'3767', 'SS14 3HG'], [u'4300', 'TA1 4DY']] 

Если они не сгруппированы, так как вы не заботитесь о том, какой элемент вы берете из в первой колонке вы можете запускать элементы через dict:

>>> [[v,k] for k,v in {k:v for v,k in your_list}.items()] 
[[u'4304', 'TA1 4DY'], [u'3772', 'SS14 3HG']] 
+0

Они, вероятно, сгруппированы вместе: чтобы указать OP: _ «Я мог бы создать цикл for, который проверяет, совпадает ли текущий элемент с следующим» _ –

+0

Да, все они сгруппированы таким образом. – Petar

+0

Это хороший ответ, но поскольку я больше знаком с методом, предложенным в ответе ajcr, я выбрал его. Однако, поскольку я буду стремиться улучшить производительность моей программы в конце концов, вы знаете, если ваш метод быстрее, чем у ajcr? Я думаю, что в какой-то момент я их проверю и сам увижу. – Petar

0

Если производительность вашей главной заботой, а элементы уже сгруппированы, есть простой и быстрый NumPy решение:

import numpy as np 

data = np.array([ 
[u'3767', u'SS14 3HG'], 
[u'3768', u'SS14 3HG'], 
[u'3769', u'SS14 3HG'], 
[u'3770', u'SS14 3HG'], 
[u'3771', u'SS14 3HG'], 
[u'3772', u'SS14 3HG'], 
[u'4300', u'TA1 4DY'], 
[u'4301', u'TA1 4DY'], 
[u'4302', u'TA1 4DY'], 
[u'4303', u'TA1 4DY'], 
[u'4304', u'TA1 4DY'], 
]) 

items, groups = data.T 
flags = np.concatenate(([True], groups[1:]!=groups[:-1])) 

print items[flags,0] 

Сортировка, выполняемая внутри np.unique, предотвращается таким образом, если вам это действительно не нужно.

В качестве альтернативы, если вы загружаете код here, вы можете написать:

group_by(groups).first(items) 

, который имеет те же характеристики, что и np.unique решение, но синтаксически чище.

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