2016-11-15 2 views
0

У меня есть список:Частота списка кортежей

a = [(['7', '8'], ['4', '7'],['3', '4'],['3', '8'],['4', '8'],...............['3','4'])] 

Я хочу создать 2 колонки, которые дают мне частоту кортежей в списке. Например:

bigram  frequency 
['7','8']  2 
['4','7']  3 
['3', '4'] 6 

и так далее.

А также рассмотрите такие записи, как ['7','8'] и ['8','7'] одинаковые (дубликаты). В столбце должна быть только одна запись, и к ней следует добавить частоту.

Я пытался использовать

from collections import counter 

и сделать некоторые петлю над ним, но я получаю сообщение об ошибке, как:

unhashable типа: список

+0

попробовать: 'Счетчик (кортеж (я) для г в [ 0]) 'потому что у вас есть список с первым кортежем элемента и внутри которого есть списки, которые необходимо преобразовать в кортеж –

+0

@ Mr.A yeah, отлично работает, спасибо, можете ли вы взглянуть на редактирование, которое я сделанный на вопрос – Shubham

+0

@Mr. Рассмотрим такие записи, как ['7', '8'] и ['8', '7'] одинаковые (дубликаты). и только одна запись должна быть в столбце, и частота должна быть добавлена ​​к этому. – Shubham

ответ

1

попробовать это:

from collections import Counter 

a = [(['7', '8'], ['4', '7'],['3', '4'],['3', '8'],['4', '8'],['3','4'],['7','8'],['8','7'],['4','3'])] 

frequency_list = Counter(tuple(sorted(i)) for i in a[0]) 

print "bigram","frequency" 
for key,val in frequency_list.items(): 
    print key, val 

выход следующим

bigram frequency 
('4', '7') 1 
('4', '8') 1 
('7', '8') 3 
('3', '4') 3 
('3', '8') 1 
+0

Сэр, он удалит мои дубликаты.? например [7,8] и [8,7], и удалить [8,7] из списка, но частота, добавленная в [7,8] – Shubham

+0

, да, это удалит дубликаты –

+0

, спасибо, сэр, это было всего лишь частью мой код, если вы поможете мне в решении этой проблемы, это будет очень полезно [щелкните ссылку] (http://stackoverflow.com/questions/40594210/create-a-bigram-from-a-column- in-pandas-df) – Shubham

3

Список не hashable для использования в качестве словарных клавиш, вам необходимо преобразовать их в хешируемый объект. Что в этом случае tuple является подходящим выбором:

In [5]: Counter(map(tuple, a[0])).items() 
Out[5]: 
[(('4', '7'), 1), 
(('4', '8'), 1), 
(('7', '8'), 1), 
(('3', '4'), 2), 
(('3', '8'), 1)] 

Если вы хотите рассмотреть unordere массивы равно вы должны отсортировать их передать их Counter:

In [7]: a 
Out[7]: 
[(['7', '8'], 
    ['4', '7'], 
    ['3', '4'], 
    ['3', '8'], 
    ['4', '8'], 
    ['3', '4'], 
    ['7', '4'])] 

In [8]: Counter(tuple(sorted(i)) for i in a[0]) 
Out[8]: Counter({('4', '7'): 2, ('3', '4'): 2, ('3', '8'): 1, ('7', '8'): 1, ('4', '8'): 1}) 

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

+0

рассматривают такие записи, как ['7', '8'] и ['8', '7'] одинаковые (дубликаты). и только одна запись должна быть в столбце, и частота должна быть добавлена ​​к этому. – Shubham

+0

спасибо, сэр, это было всего лишь частью моего кода, если бы вы помогли мне в решении этой проблемы, это будет очень полезно [щелкните ссылку] (http://stackoverflow.com/questions/40594210/create- a-bigram-from-a-column-in-pandas-df) – Shubham

+0

Возможно, нет необходимости сначала преобразовывать их в целые числа, так как функция 'sorted' является последовательной, неважно, что мы сортируем' ['3' , '1', '2'] 'to' ['1', '2', '3'] 'или' ['1', '3', '2'] ', только если согласованность может быть гарантирована , дубликаты не будут существовать в конечном выпуске. – Jason

2

Это будет работать, используя счетчик, если вы измените свой список: a = [('7', '8'), ... ('4', '7')]

Или вы можете отобразить списки кортежей, потому что кортежи hashable, но не списки.

[Обновить] Сортировка, а затем отображение каждого из ваших списков на кортежи в первую очередь. Counter(map(lambda x: tuple(sorted(x)), a[0])).items() (Основано на @ Kasramvd).

+0

рассматривают такие записи, как ['7', '8'] и ['8', '7'] одинаковые (дубликаты). и только одна запись должна быть в столбце, и частота должна быть добавлена ​​к этому. – Shubham

+0

См. Обновление. @SRingne – Jason

+0

Сэр, он удалит дубликаты записей, как я уже упоминал? – Shubham

0

Я думаю, вы можете использовать itertools.groupby для группировки отсортированного списка предметов. Ключом к группе может быть пользовательский ключ, который может создать упорядоченный список. Для бинарного кортежа, вы можете использовать простое сравнение, чтобы создать такой кортеж

Учитывая

a = [(['7', '8'], ['4', '7'],['3', '4'],['3', '8'],['4', '8'],['4','3'])] 


from itertools import groupby 
key = lambda tup: tup if tup[0] < tup[1] else tup[::-1] 
[(key, len(list(values))) 
for key, values in groupby(sorted(a[0], key = key), key = key)] 
Out[42]: 
[(['3', '4'], 2), 
(['3', '8'], 1), 
(['4', '7'], 1), 
(['4', '8'], 1), 
(['7', '8'], 1)] 

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

[(key, len(list(values))) 
for key, values in groupby(sorted(a[0], key = sorted), key = sorted)] 
Out[37]: 
[(['3', '4'], 2), 
(['3', '8'], 1), 
(['4', '7'], 1), 
(['4', '8'], 1), 
(['7', '8'], 1)] 
+0

Сэр, он удалит мои дубликаты.? например, [7,8] и [8,7] одинаковы и удаляют [8,7] из списка, но частоту, добавленную в [7,8] – Shubham

+0

@SRingne: Да. См. Мой пример выше – Abhijit

+0

спасибо, сэр, это было всего лишь частью моего кода, если вы поможете мне в решении этой проблемы, это будет очень полезно [щелкните ссылку] (http://stackoverflow.com/questions/ 40594210/create-a-bigram-from-a-column-in-pandas-df) – Shubham