2017-02-22 3 views
3

Actuellement, je fais une analyse de fréquence sur un fichier texte qui montre les 100 mots les plus utilisés dans le fichier texte. Actuellement, je suis en utilisant ce code:Python - afficher des mots fréquents dans une table et ignorer certains mots

from collections import Counter 
import re 
words = re.findall(r'\w+', open('tweets.txt').read().lower()) 
print Counter(words).most_common (100) 

Le code ci-dessus fonctionne et les sorties sont:

[('the', 1998), ('t', 1829), ('https', 1620), ('co', 1604), ('to', 1247), ('and', 1053), ('in', 957), ('a', 899), ('of', 821), ('i', 789), ('is', 784), ('you', 753), ('will', 654), ('for', 601), ('on', 574), ('thank', 470), ('be', 455), ('great', 447), ('hillary', 440), ('we', 390), ('that', 373), ('s', 363), ('it', 346), ('with', 345), ('at', 333), ('me', 327), ('are', 311), ('amp', 290), ('clinton', 288), ('trump', 287), ('have', 286), ('our', 264), ('realdonaldtrump', 256), ('my', 244), ('all', 237), ('crooked', 236), ('so', 233), ('by', 226), ('this', 222), ('was', 217), ('people', 216), ('has', 210), ('not', 210), ('just', 210), ('america', 204), ('she', 190), ('they', 188), ('trump2016', 180), ('very', 180), ('make', 180), ('from', 175), ('rt', 170), ('out', 169), ('he', 168), ('her', 164), ('makeamericagreatagain', 164), ('join', 161), ('as', 158), ('new', 157), ('who', 155), ('again', 154), ('about', 145), ('no', 142), ('get', 138), ('more', 137), ('now', 136), ('today', 136), ('president', 135), ('can', 134), ('time', 123), ('media', 123), ('vote', 117), ('but', 117), ('am', 116), ('bad', 116), ('going', 115), ('maga', 112), ('u', 112), ('many', 110), ('if', 110), ('country', 108), ('big', 108), ('what', 107), ('your', 105), ('cnn', 105), ('never', 104), ('one', 101), ('up', 101), ('back', 99), ('jobs', 98), ('tonight', 97), ('do', 97), ('been', 97), ('would', 94), ('obama', 93), ('tomorrow', 88), ('said', 88), ('like', 88), ('should', 87), ('when', 86)] 

Cependant, je veux afficher sous forme de table avec un en-tête « Word » et " Compter". Je l'ai essayé d'utiliser le paquet prettytable et est venu avec ceci:

from collections import Counter 
import re 
import prettytable 

words = re.findall(r'\w+', open('tweets.txt').read().lower()) 

for label, data in ('Word', words): 
    pt = prettytable(field_names=[label, 'Count']) 
    c = Counter(data) 
    [pt.add_row(kv) for kv in c.most_common() [:100] ] 
    pt.align [label], pt.align['Count'] = '1', 'r' 
    print pt 

Il me donne ValueError: too many values to unpack. Ma question est, quel est le problème avec mon code et est-il un moyen d'afficher les données en utilisant prettytable? Aussi, comment puis-je réparer mon code? Question bonus: Existe-t-il un moyen d'omettre certains mots en comptant la fréquence? par exemple ignorer les mots: et, si, de etc etc

Merci.

+0

Sur quelle ligne est l'erreur? Mettez à jour la question –

+0

Qu'est-ce que '('Word', mots)'? –

+0

l'erreur est dans cette ligne "pour l'étiquette, les données dans ('Word', mots):" – Vin23

Répondre

2

Je ne sais pas comment vous vous attendiez à ce que la boucle for que vous avez écrite fonctionne. L'erreur que vous obtenez est parce que vous essayez d'itérer sur le tuple ('Word', words) qui a deux éléments. L'instruction for label, data in ('Word', words) tente d'affecter 'W' à label, 'o' à data et se termine par 'r' et 'd' restant à la première itération. Peut-être que vous vouliez fermer les objets ensemble à la place? Mais alors pourquoi faites-vous une nouvelle table pour chaque mot?

Voici une version réécrite:

from collections import Counter 
import re, prettytable 

words = re.findall(r'\w+', open('tweets.txt').read().lower()) 
c = Counter(words) 
pt = prettytable.PrettyTable(['Words', 'Counts']) 
pt.align['Words'] = 'l' 
pt.align['Counts'] = 'r' 
for row in c.most_common(100): 
    pt.add_row(row) 
print pt 

Pour sauter des éléments dans le nombre le plus courant, vous pouvez simplement les jeter du compteur avant d'appeler most_common. Un moyen facile de le faire est de définir une liste de mots non valides, puis de les filtrer avec une compréhension dict:

bad_words = ['the', 'if', 'of'] 
c = Counter({k: v for k, v in c.items() if k not in bad_words}) 

Alternativement, vous pouvez faire le filtrage sur la liste des mots avant de faire un compteur en dehors de cela:

words = filter(lambda x: x not in bad_words, words) 

Je préfère opérer sur le compteur car cela nécessite moins de travail puisque les données ont déjà été agrégées.Voici le code combiné de référence:

from collections import Counter 
import re, prettytable 

bad_words = ['the', 'if', 'of'] 
words = re.findall(r'\w+', open('tweets.txt').read().lower()) 

c = Counter(words) 
c = Counter({k: v for k, v in c.items() if k not in bad_words}) 

pt = prettytable.PrettyTable(['Words', 'Counts']) 
pt.align['Words'] = 'l' 
pt.align['Counts'] = 'r' 
for row in c.most_common(100): 
    pt.add_row(row) 

print(pt) 
+0

J'ai reçu une erreur de votre code. Fichier "test4.py", ligne 7, dans pt.set_field_names (["Words", "Counts"]) Fichier "C: \ Python27 \ lib \ site-packages \ prettytable.py", ligne 217, dans __getattr__ raise AttributeError (nom) AttributeError: set_field_names – Vin23

+0

@ Vin23. J'ai réparé ça. –

+0

@ Vin23. Les documents sont un peu périmés pour la bibliothèque, ma première version était basée sur cela. –

1

Est-ce ce que vous essayez de faire?

from prettytable import PrettyTable 

x = PrettyTable(["Words", "Counts"]) 

L = [('the', 1998), ('t', 1829), ('https', 1620), ('co', 1604), ('to', 1247), ('and', 1053), ('in', 957), ('a', 899), ('of', 821), ('i', 789), ('is', 784), ('you', 753), ('will', 654), ('for', 601), ('on', 574), ('thank', 470), ('be', 455), ('great', 447), ('hillary', 440), ('we', 390), ('that', 373), ('s', 363), ('it', 346), ('with', 345), ('at', 333), ('me', 327), ('are', 311), ('amp', 290), ('clinton', 288), ('trump', 287), ('have', 286), ('our', 264), ('realdonaldtrump', 256), ('my', 244), ('all', 237), ('crooked', 236), ('so', 233), ('by', 226), ('this', 222), ('was', 217), ('people', 216), ('has', 210), ('not', 210), ('just', 210), ('america', 204), ('she', 190), ('they', 188), ('trump2016', 180), ('very', 180), ('make', 180), ('from', 175), ('rt', 170), ('out', 169), ('he', 168), ('her', 164), ('makeamericagreatagain', 164), ('join', 161), ('as', 158), ('new', 157), ('who', 155), ('again', 154), ('about', 145), ('no', 142), ('get', 138), ('more', 137), ('now', 136), ('today', 136), ('president', 135), ('can', 134), ('time', 123), ('media', 123), ('vote', 117), ('but', 117), ('am', 116), ('bad', 116), ('going', 115), ('maga', 112), ('u', 112), ('many', 110), ('if', 110), ('country', 108), ('big', 108), ('what', 107), ('your', 105), ('cnn', 105), ('never', 104), ('one', 101), ('up', 101), ('back', 99), ('jobs', 98), ('tonight', 97), ('do', 97), ('been', 97), ('would', 94), ('obama', 93), ('tomorrow', 88), ('said', 88), ('like', 88), ('should', 87), ('when', 86)] 


for e in L: 
    x.add_row([e[0],e[1]]) 

print x 

Voici le résultat:

+-----------------------+--------+ 
|   Words   | Counts | 
+-----------------------+--------+ 
|   the   | 1998 | 
|   t   | 1829 | 
|   https   | 1620 | 
|   co   | 1604 | 
|   to   | 1247 | 
|   and   | 1053 | 
|   in   | 957 | 
|   a   | 899 | 
|   of   | 821 | 
|   i   | 789 | 
|   is   | 784 | 
|   you   | 753 | 
|   will   | 654 | 
|   for   | 601 | 
|   on   | 574 | 
|   thank   | 470 | 
|   be   | 455 | 
|   great   | 447 | 
|  hillary  | 440 | 
|   we   | 390 | 
|   that   | 373 | 
|   s   | 363 | 
|   it   | 346 | 
|   with   | 345 | 
|   at   | 333 | 
|   me   | 327 | 
|   are   | 311 | 
|   amp   | 290 | 
|  clinton  | 288 | 
|   trump   | 287 | 
|   have   | 286 | 
|   our   | 264 | 
| realdonaldtrump | 256 | 
|   my   | 244 | 
|   all   | 237 | 
|  crooked  | 236 | 
|   so   | 233 | 
|   by   | 226 | 
|   this   | 222 | 
|   was   | 217 | 
|   people  | 216 | 
|   has   | 210 | 
|   not   | 210 | 
|   just   | 210 | 
|  america  | 204 | 
|   she   | 190 | 
|   they   | 188 | 
|  trump2016  | 180 | 
|   very   | 180 | 
|   make   | 180 | 
|   from   | 175 | 
|   rt   | 170 | 
|   out   | 169 | 
|   he   | 168 | 
|   her   | 164 | 
| makeamericagreatagain | 164 | 
|   join   | 161 | 
|   as   | 158 | 
|   new   | 157 | 
|   who   | 155 | 
|   again   | 154 | 
|   about   | 145 | 
|   no   | 142 | 
|   get   | 138 | 
|   more   | 137 | 
|   now   | 136 | 
|   today   | 136 | 
|  president  | 135 | 
|   can   | 134 | 
|   time   | 123 | 
|   media   | 123 | 
|   vote   | 117 | 
|   but   | 117 | 
|   am   | 116 | 
|   bad   | 116 | 
|   going   | 115 | 
|   maga   | 112 | 
|   u   | 112 | 
|   many   | 110 | 
|   if   | 110 | 
|  country  | 108 | 
|   big   | 108 | 
|   what   | 107 | 
|   your   | 105 | 
|   cnn   | 105 | 
|   never   | 104 | 
|   one   | 101 | 
|   up   | 101 | 
|   back   | 99 | 
|   jobs   | 98 | 
|  tonight  | 97 | 
|   do   | 97 | 
|   been   | 97 | 
|   would   | 94 | 
|   obama   | 93 | 
|  tomorrow  | 88 | 
|   said   | 88 | 
|   like   | 88 | 
|   should  | 87 | 
|   when   | 86 | 
+-----------------------+--------+ 

EDIT 1: Si vous voulez laisser de côté certains que vous pourriez faire quelque chose comme ça:

for e in L: 
    if e[0]!="and" or e[0]!="if" or e[0]!="of": 
     x.add_row([e[0],e[1]]) 

EDIT 2: pour résumer:

from collections import Counter 
import re 

words = re.findall(r'\w+', open('tweets.txt').read().lower()) 
counts = Counter(words).most_common (100) 

from prettytable import PrettyTable 

x = PrettyTable(["Words", "Counts"]) 

skip_list = ['and','if','or'] # see joe's comment 

for e in counts: 
    if e[0] not in skip_list: 
     x.add_row([e[0],e[1]]) 

print x 
+0

Oui, quelque chose comme ça. mais est-il possible de ne pas avoir les longues listes de mots différents? – Vin23

+0

Vous voulez dire que vous voulez choisir chaque donnée du fichier texte et la placer directement dans le tableau? Pouvez-vous me donner un lien du fichier texte? Je veux voir comment les données sont rangées dans le fichier. –

+0

Vous pouvez définir 'skip_list = ['et', 'if', 'ou']' et 'if e [0] pas dans skip_list:' –