2016-07-29 3 views
1

Следуя этому примеру: Twitter data mining with Python and Gephi: Case synthetic biologyПанды NLTK tokenizing "unhashable типа: 'список'"

CSV to: df['Country', 'Responses']

'Country' 
Italy 
Italy 
France 
Germany 

'Responses' 
"Loren ipsum..." 
"Loren ipsum..." 
"Loren ipsum..." 
"Loren ipsum..." 
  1. разметить текст в 'Ответы'
  2. удалить 100 наиболее употребительных слов (на основе brown.corpus)
  3. идентифицировать оставшиеся 100 наиболее часто встречающихся слов

я могу пройти шаг 1 и 2, но получаю сообщение об ошибке на шаге 3:

TypeError: unhashable type: 'list' 

Я считаю, что это потому, что я работаю в dataframe и сделали это (вероятно erronous) модификация:

Оригинальный пример:

#divide to words 
tokenizer = RegexpTokenizer(r'\w+') 
words = tokenizer.tokenize(tweets) 

Мой код:

#divide to words 
tokenizer = RegexpTokenizer(r'\w+') 
df['tokenized_sents'] = df['Responses'].apply(nltk.word_tokenize) 

Моего полный код:

df = pd.read_csv('CountryResponses.csv', encoding='utf-8', skiprows=0, error_bad_lines=False) 

tokenizer = RegexpTokenizer(r'\w+') 
df['tokenized_sents'] = df['Responses'].apply(nltk.word_tokenize) 

words = df['tokenized_sents'] 

#remove 100 most common words based on Brown corpus 
fdist = FreqDist(brown.words()) 
mostcommon = fdist.most_common(100) 
mclist = [] 
for i in range(len(mostcommon)): 
    mclist.append(mostcommon[i][0]) 
words = [w for w in words if w not in mclist] 

Out: ['the', 
',', 
'.', 
'of', 
'and', 
...] 

#keep only most common words 
fdist = FreqDist(words) 
mostcommon = fdist.most_common(100) 
mclist = [] 
for i in range(len(mostcommon)): 
    mclist.append(mostcommon[i][0]) 
words = [w for w in words if w not in mclist] 

TypeError: unhashable type: 'list' 

Есть много вопросов по unhashable списков, но никто, что я понимаю, что совсем то же самое. Любые предложения? Благодарю.


след вызовов TRACEBACK

TypeError         Traceback (most recent call last) 
<ipython-input-164-a0d17b850b10> in <module>() 
    1 #keep only most common words 
----> 2 fdist = FreqDist(words) 
    3 mostcommon = fdist.most_common(100) 
    4 mclist = [] 
    5 for i in range(len(mostcommon)): 

/home/*******/anaconda3/envs/*******/lib/python3.5/site-packages/nltk/probability.py in __init__(self, samples) 
    104   :type samples: Sequence 
    105   """ 
--> 106   Counter.__init__(self, samples) 
    107 
    108  def N(self): 

/home/******/anaconda3/envs/******/lib/python3.5/collections/__init__.py in __init__(*args, **kwds) 
    521    raise TypeError('expected at most 1 arguments, got %d' % len(args)) 
    522   super(Counter, self).__init__() 
--> 523   self.update(*args, **kwds) 
    524 
    525  def __missing__(self, key): 

/home/******/anaconda3/envs/******/lib/python3.5/collections/__init__.py in update(*args, **kwds) 
    608      super(Counter, self).update(iterable) # fast path when counter is empty 
    609    else: 
--> 610     _count_elements(self, iterable) 
    611   if kwds: 
    612    self.update(kwds) 

TypeError: unhashable type: 'list' 
+0

что тип элемента в словах – galaxyan

+0

Они строки (английские фразы) –

+0

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

ответ

1

FreqDist функция принимает в качестве итератора из hashable объектов (заставлены быть струнные, но это, вероятно, работает с любым). Ошибка, которую вы получаете, заключается в том, что вы передаете итерируемый список. Как вы предложили, это из-за изменения вы сделали:

df['tokenized_sents'] = df['Responses'].apply(nltk.word_tokenize) 

Если я понимаю Pandas apply function documentation правильно, что линия применяет функцию nltk.word_tokenize к некоторой серии. word-tokenize возвращает список слов.

В качестве решения, просто добавьте списки вместе, прежде чем пытаться применить FreqDist, например, так:

allWords = [] 
for wordList in words: 
    allWords += wordList 
FreqDist(allWords) 

Более полный пересмотр, чтобы делать то, что вы хотели. Если вам нужно только идентифицировать второй набор из 100, обратите внимание, что во втором случае это будет mclist.

df = pd.read_csv('CountryResponses.csv', encoding='utf-8', skiprows=0, error_bad_lines=False) 

tokenizer = RegexpTokenizer(r'\w+') 
df['tokenized_sents'] = df['Responses'].apply(nltk.word_tokenize) 

lists = df['tokenized_sents'] 
words = [] 
for wordList in lists: 
    words += wordList 

#remove 100 most common words based on Brown corpus 
fdist = FreqDist(brown.words()) 
mostcommon = fdist.most_common(100) 
mclist = [] 
for i in range(len(mostcommon)): 
    mclist.append(mostcommon[i][0]) 
words = [w for w in words if w not in mclist] 

Out: ['the', 
',', 
'.', 
'of', 
'and', 
...] 

#keep only most common words 
fdist = FreqDist(words) 
mostcommon = fdist.most_common(100) 
mclist = [] 
for i in range(len(mostcommon)): 
    mclist.append(mostcommon[i][0]) 
# mclist contains second-most common set of 100 words 
words = [w for w in words if w in mclist] 
# this will keep ALL occurrences of the words in mclist 
+0

Спасибо. Я сделаю это.Интересно, если это позволит мне устранить 100 наиболее распространенных 100 английских слов, а затем определить 100 наиболее часто встречающихся в текстах? Я попробую ... –

+0

Да, это не делает 'set' из слов, просто помещая их все в один список. поэтому достаточно просто использовать ваше понимание списка 'words = [w для w в словах, если w не в most_common_english_words]', а затем функция 'most_common', как вы. –

+0

Спасибо. Я попытался добавить списки вместе, но получил нулевой набор: 'words []'. Я понимаю, что первая функция удаляет наиболее распространенные слова в соответствии с Брауном, возвращая оставшиеся слова во вторую функцию, чтобы снова идентифицировать 100 наиболее распространенных слов, но на этот раз удерживая их помещением в 'mclist []'. Я продолжаю пытаться ... –

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