Python, Wörterbücher und Chi-Quadrat-Kontingenztabelle

Dies ist ein Problem, das ich schon seit langem auf meine Gehirne geraten habe, also wäre jede Hilfe großartig. Ich habe eine Datei, die mehrere Zeilen in folgendem Format enthält (Wort, Zeit, in der das Wort eingetreten ist, und Häufigkeit der Dokumente, die das gegebene Wort innerhalb der gegebenen Instanz in der Zeit enthalten). Unten ist ein Beispiel dafür, wie die Eingangsdatei aussieht.

#inputfile <word, time, frequency> apple, 1, 3 banana, 1, 2 apple, 2, 1 banana, 2, 4 orange, 3, 1 

Ich habe Python-Klasse unten, dass ich verwendet, um 2-D-Wörterbücher zu erstellen, um die oben genannten Datei mit dem Schlüssel zu speichern, und Häufigkeit als Wert:

 class Ddict(dict): ''' 2D dictionary class ''' def __init__(self, default=None): self.default = default def __getitem__(self, key): if not self.has_key(key): self[key] = self.default() return dict.__getitem__(self, key) wordtime=Ddict(dict) # Store each inputfile entry with a <word,time> key timeword=Ddict(dict) # Store each inputfile entry with a <time,word> key # Loop over every line of the inputfile for line in open('inputfile'): word,time,count=line.split(',') # If <word,time> already a key, increment count try: wordtime[word][time]+=count # Otherwise, create the key except KeyError: wordtime[word][time]=count # If <time,word> already a key, increment count try: timeword[time][word]+=count # Otherwise, create the key except KeyError: timeword[time][word]=count 

Die Frage, die ich habe, um bestimmte Dinge zu berechnen, während Iteration über die Einträge in diesem 2D Wörterbuch. Für jedes Wort 'w' zu jedem Zeitpunkt 't' berechnen:

  1. Die Anzahl der Dokumente mit dem Wort 'w' innerhalb der Zeit 't'. (ein)
  2. Die Anzahl der Dokumente ohne Wort 'w' innerhalb der Zeit 't'. (B)
  3. Die Anzahl der Dokumente mit dem Wort 'w' außerhalb der Zeit 't'. (C)
  4. Die Anzahl der Dokumente ohne Wort 'w' außerhalb der Zeit 't'. (D)

Jedes der obigen Punkte repräsentiert eine der Zellen einer chi-quadratischen Kontingenztabelle für jedes Wort und jede Zeit. Können alle diese innerhalb einer einzigen Schleife berechnet werden oder müssen sie zu einem Zeitpunkt fertig sein?

Im Idealfall möchte ich, dass die Ausgabe das ist, was unten ist, wo a, b, c, d alle oben berechneten Elemente sind:

 print "%s, %s, %s, %s" %(a,b,c,d) 

Im Falle der oben genannten Eingabedatei wäre das Ergebnis des Versuches, die Kontingenztabelle für das Wort "Apfel" zum Zeitpunkt '1' zu finden, (3,2,1,6) . Ich werde erklären, wie jede Zelle berechnet wird:

  • '3' Dokumente enthalten 'Apfel' innerhalb der Zeit '1'.
  • Es gibt '2' Dokumente innerhalb der Zeit '1', die nicht 'Apfel' enthalten.
  • Es gibt '1' Dokument mit 'Apfel' außerhalb der Zeit '1'.
  • Es gibt 6 Dokumente außerhalb der Zeit '1', die nicht das Wort 'Apfel' (1 + 4 + 1) enthalten.

  • Query Python Wörterbuch, um Wert aus Tupel zu erhalten
  • Schreiben und Lesen eines Wörterbuchs im bestimmten Format (Python)
  • Konvertieren Sie eine Liste von Wörterbüchern in ein Wörterbuch
  • Traversing multidimensionales Wörterbuch in django
  • Auswählen von Elementen eines Python-Wörterbuchs größer als ein bestimmter Wert
  • Pythonic way für FIFO Ordnung auf Wörterbuch
  • Referenzieren und Festlegen von Variablen in Python-Dicts
  • Python - Parsing JSON Datensatz
  • One Solution collect form web for “Python, Wörterbücher und Chi-Quadrat-Kontingenztabelle”

    Ihre 4 Zahlen für Apfel / 1 bis zu 12, mehr als die Gesamtzahl der Beobachtungen (11)! Es gibt nur 5 Dokumente außerhalb der Zeit '1', die nicht das Wort 'Apfel' enthalten.

    Sie müssen die Beobachtungen in 4 disjunkte Teilmengen aufteilen:
    A: apfel und 1 => 3
    B: nicht-apfel und 1 => 2
    C: apfel und nicht-1 => 1
    D: Nicht-Apfel und nicht-1 => 5

    Hier ist ein Code, der eine Möglichkeit zeigt, es zu tun:

     from collections import defaultdict class Crosstab(object): def __init__(self): self.count = defaultdict(lambda: defaultdict(int)) self.row_tot = defaultdict(int) self.col_tot = defaultdict(int) self.grand_tot = 0 def add(self, r, c, n): self.count[r][c] += n self.row_tot[r] += n self.col_tot[c] += n self.grand_tot += n def load_data(line_iterator, conv_funcs): ct = Crosstab() for line in line_iterator: r, c, n = [func(s) for func, s in zip(conv_funcs, line.split(','))] ct.add(r, c, n) return ct def display_all_2x2_tables(crosstab): for rx in crosstab.row_tot: for cx in crosstab.col_tot: a = crosstab.count[rx][cx] b = crosstab.col_tot[cx] - a c = crosstab.row_tot[rx] - a d = crosstab.grand_tot - a - b - c assert all(x >= 0 for x in (a, b, c, d)) print ",".join(str(x) for x in (rx, cx, a, b, c, d)) if __name__ == "__main__": # inputfile # <word, time, frequency> lines = """\ apple, 1, 3 banana, 1, 2 apple, 2, 1 banana, 2, 4 orange, 3, 1""".splitlines() ct = load_data(lines, (str.strip, int, int)) display_all_2x2_tables(ct) 

    Und hier ist die Ausgabe:

     orange,1,0,5,1,5 orange,2,0,5,1,5 orange,3,1,0,0,10 apple,1,3,2,1,5 apple,2,1,4,3,3 apple,3,0,1,4,6 banana,1,2,3,4,2 banana,2,4,1,2,4 banana,3,0,1,6,4 
    Python ist die beste Programmiersprache der Welt.