2016-06-03 9 views
2

Ich versuche, die Häufigkeiten für Häufigkeiten von Wörtern in mehreren Dateien in einem Verzeichnis zu erhalten, und dank dieser Antwort here konnte ich Ergebnisse erhalten, wenn das Wort aufgetreten ist. Ich kann jedoch nicht herausfinden, wie die Ergebnisse auch dann angezeigt werden, wenn es 0 Vorkommen des Wortes gibt.Wie erhält man die Worthäufigkeit mit Hilfe von Collections.Counter, selbst wenn der Zählerstand null ist?

z.B. Dies ist die Art von Ergebnis, das ich will, so bekomme ich immer Ergebnisse für alle angegebenen Wörter, mit dem angegebenen Wort in der ersten Zeile und der Zählung unten.

21, 23, 60 4, 0, 8

Hier ist mein aktueller Code:

import csv 
import copy 
import os 
import sys 
import glob 
import string 
import fileinput 
from collections import Counter 

def word_frequency(fileobj, words): 
    """Build a Counter of specified words in fileobj""" 
    # initialise the counter to 0 for each word 
    ct = Counter(dict((w, 0) for w in words)) 
    file_words = (word for line in fileobj for word in line.split()) 
    filtered_words = (word for word in file_words if word in words) 
    return Counter(filtered_words) 


def count_words_in_dir(dirpath, words, action): 
    """For each .txt file in a dir, count the specified words""" 
     for filepath in glob.iglob(os.path.join(dirpath, '*.txt_out')): 
      filepath = {} 
     with open(filepath) as f: 
      ct = word_frequency(f, words) 
      action(filepath, ct) 


def final_summary(filepath, ct): 
    words = sorted(ct.keys()) 
    counts = [str(ct[k]) for k in words] 
    with open('new.csv','a') as f: 
     [f.write('{0},{1}\n,{2}\n'.format(
      filepath, 
     ', '.join(words), 
     ', '.join(counts)))] 


words = set(['21','23','60','75','79','86','107','121','147','193','194','197','198','199','200','201','229','241','263','267','309','328']) 
count_words_in_dir('C:\\Users\jllevent\Documents\PE Submsissions\Post-CLI', words, action=final_summary) 
+0

einige zusätzliche Anmerkungen:

... for word in file_words: if word in words: ct[word] += 1 return ct 

Oder wie @ShadowRanger unten wies darauf hin, Sie einige Arbeit zu initialisieren 'ct', indem man' dict sparen .fromkey s' mach die Arbeit für dich: 'ct = Counter (dict.frunkkeys (words, 0))'. Und Sie können auf andere Weise mehr Arbeit auf die C-Schicht schieben, indem Sie eingebaute C-eingebaute Funktionen verwenden, z. 'file_words = itertools.chain.from_iterable (map (str.split, fileobj))' und 'filteredwords = filter (frozenset (words) .__ contains__, file_words)', gefolgt von 'Counter.update (filtered_words)' (obwohl 'Counter .update' ist in Python implementiert, das Heavy Lifting im modernen Python erfolgt durch die C accelerated 'collections._count_elements'). – ShadowRanger

+0

Hinweis: 'map' und' filter' sollten die Python 3-Versionen sein, um die beste Leistung ohne große verschwenderische temporäre Objekte zu erzielen; In Python 2 können Sie 'from future_builtins importieren map, filter', um die generatorbasierten Versionen dieser Funktionen zu erhalten. Wenn Sie Python 2.7/3.1 oder höher verwenden, können Sie 'set' Literale anstelle von' list' Literalen verwenden, die in 'set' Konstruktor eingepackt sind:' word = {'21', '23', '60' 75, 79, 86, 107, 121, 147, 193, 194, 197, 198, 199, 200, 201 ',' 229 ',' 241 ',' 263 ',' 267 ',' 309 ',' 328 '} ' – ShadowRanger

Antwort

1

Du nie die ct Zähler mit Ihnen in word_frequency konstruiert, sondern einen neuen Zähler erstellt, die nur die vorhandenen Wörter hat , müssen Sie Ihre ct gebaut verwenden, zB:

ct.update(word for word in file_words if word in words) 
return ct 
+0

Das hat den Job gemacht! Vielen Dank :) –

+1

'Counter' hat eine' update' Methode, die das wesentlich vereinfachen (und beschleunigen) würde: 'ct.update (Wort für Wort in file_words wenn Wort in Worten)'. – ShadowRanger

-1

Es sieht aus wie es NULL ist zurückkehrt, wenn das Wort nicht angezeigt. Setzen Sie in einem konditionierten return-Anweisung, in dem, wenn der Wert der Rückgabe ist kein int> 0, wird 0 geliefert