Подсчитывать уникальные кортежи во вложенном списке

#python #arrays #list #dictionary

#python #массивы #Список #словарь

Вопрос:

У меня есть 2D-массив, где каждый элемент представляет собой пару из двух тегов, например [«СУЩЕСТВИТЕЛЬНОЕ», «ГЛАГОЛ»], и я хочу подсчитать, сколько раз каждая из этих уникальных пар встречается в большом наборе данных.

До сих пор я пытался использовать defaultdict (int) и Counter (), чтобы просто добавить элемент, если он ранее не найден, или, если найден, увеличить значение на 1.

 dTransition = Counter()
# dTransition = defaultdict(int)

# <s> is a start of sentence tag
pairs = [[('<s>', 'NOUN')], [('CCONJ', 'NOUN')], [('NOUN', 'SCONJ')], [('SCONJ', 'NOUN')]]

for pair in pairs:
      dTransition[pairs]  = 1

  

Это не работает, поскольку не принимает два аргумента. Итак, мне интересно, есть ли простой способ проверить словарь, если ключ, представляющий собой 2D-массив, уже существует, и если да, увеличьте значение на 1.

Ответ №1:

Вам нужно выровнять свой список, учитывая, что в отличие от списков, кортежи являются хэшируемыми. Простой вариант — использовать itertools.chain , а затем создавать Counter из списка кортежей:

 from itertools import chain
Counter(chain(*pairs))
  

Вывод

 Counter({('<s>', 'NOUN'): 1, ('CCONJ', 'NOUN'): 1, 
         ('NOUN', 'SCONJ'): 1, ('SCONJ', 'NOUN'): 1})
  

Комментарии:

1. Большое спасибо, это сработало, а также был очень чистый и простой способ сделать это!

2. Это волшебство следующего уровня, спасибо.

Ответ №2:

Для этого можно использовать массив numpy с уже встроенной функцией.

 import numpy as np

#convert array to numpy array
pairs= np.array(pairs)

#pairs.unique() returns an array with only the unique elements
#len() returns the length(count) of unique pairs
count= len(pairs.unique())
  

Ответ №3:

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

 import collections 
dTransition = collections.defaultdict(int)

# <s> is a start of sentence tag
pairs = [[('<s>', 'NOUN')], [('CCONJ', 'NOUN')], [('NOUN', 'SCONJ')], [('SCONJ', 'NOUN')],[('SCONJ', 'NOUN')]]

for pair in pairs:
      dTransition[pair[0]]  = 1
  

Тогда это работает