2016-07-29 6 views
1

Nach diesem Beispiel: Twitter data mining with Python and Gephi: Case synthetic biologyPandas NLTK Tokenisieren "unhashable Typ: 'list'"

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

'Country' 
Italy 
Italy 
France 
Germany 

'Responses' 
"Loren ipsum..." 
"Loren ipsum..." 
"Loren ipsum..." 
"Loren ipsum..." 
  1. tokenize den Text in 'Antworten'
  2. entfernen Sie die 100 häufigsten Wörter (basierend auf brown.corpus)
  3. identifizieren Sie die restlichen 100 häufigsten Wörter

Ich kann durch den Schritt 1 und 2, erhalten aber einen Fehler in Schritt 3 erhalten:

TypeError: unhashable type: 'list' 

Ich glaube, es ist, weil ich arbeite in einem Datenrahmen und gemacht haben diese (wahrscheinlich falsch empfangenen) Änderung:

Original-Beispiel:

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

Mein Code:

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

Mein vollständige Code:

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' 

Es gibt viele Fragen auf unhashable Listen sind, aber keine, die ich verstehe, dass sie gleich sind recht. Irgendwelche Vorschläge? Vielen Dank.


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

, was die Art des Elements ist in Worten – galaxyan

+0

Sie sind Strings (englische Sätze) –

+0

können Sie ausdrucken und überprüfen. Es scheint, dass Sie darin eine Liste haben – galaxyan

Antwort

1

Die FreqDist Funktion in einem iterable von hashable Objekte nimmt (hergestellt Saiten sein, aber es funktioniert wahrscheinlich mit was auch immer). Der Fehler, den Sie bekommen, liegt daran, dass Sie eine iterierbare Liste übergeben. Wie Sie vorgeschlagen, dies ist wegen der Änderung, die Sie gemacht:

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

Wenn ich die Pandas apply function documentation richtig verstehe, ist diese Linie zu einigen Serien die nltk.word_tokenize Funktion anwenden. word-tokenize gibt eine Liste von Wörtern zurück.

Als Lösung fügen Sie einfach die zusammen Listen, bevor Sie versuchen FreqDist anzuwenden, etwa so:

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

Eine vollständige Überarbeitung zu tun, was Sie möchten. Wenn Sie nur den zweiten Satz von 100 identifizieren müssen, beachten Sie, dass mclist das zweite Mal haben wird.

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

Danke. Ich versuche es mal.Ich frage mich, ob es mir erlaubt, die 100 häufigsten 100 englischen Wörter zu eliminieren und dann die 100 häufigsten in den Texten zu identifizieren. Ich werde es ausprobieren ... –

+0

Ja, es macht kein 'Set' aus den Wörtern, sondern bringt sie alle in eine Liste. Es ist also leicht genug, das Listenverstehen 'words = [w für w in Wörtern, wenn nicht in den meisten_common_english_words]' zu verwenden und dann die 'most_common'-Funktion, wie Sie sie haben. –

+0

Danke. Ich habe versucht, die Listen zu addieren, aber ich habe eine Nullmenge bekommen: 'words []'. Nach meinem Verständnis entfernt die erste Funktion die gebräuchlichsten Wörter nach Brown und gibt die restlichen Wörter an die zweite Funktion zurück, um die 100 häufigsten Wörter wieder zu identifizieren, wobei sie diesmal in "mclist []" eingefügt werden. Ich werde es weiter versuchen ... –