Как сравнить частоты слов из двух текстовых файлов?

Как сравнить частоты слов из двух текстовых файлов в python? Например, если слово содержится и в файле1, и в файле2, то оно должно быть записано только один раз, но без прибавления частот при сравнении, оно должно быть {'The': 3,5}. Здесь 3 — частота в файле 1, а 5 — частота в файле 2. И если некоторые слова существуют только в одном файле, но не в обоих, тогда для этого файла должно быть 0. Пожалуйста, помогите Вот что я сделал до сих пор:

import operator
f1=open('file1.txt','r') #file 1
f2=open('file2.txt','r') #file 2

wordlist=[]
wordlist2=[]
for line in f1:
    for word in line.split():
        wordlist.append(word)

for line in f2:
    for word in line.split():
        wordlist2.append(word)

worddictionary = {}
for word in wordlist:
    if word in worddictionary:
        worddictionary[word] += 1
    else:
        worddictionary[word] = 1

worddictionary2 = {}
for word in wordlist2:
    if word in worddictionary2:
        worddictionary2[word] += 1
    else:
        worddictionary2[word] = 1

print(worddictionary)
print(worddictionary2)

person iOwais    schedule 07.11.2018    source источник
comment
А что не так с тем, что у вас есть?   -  person mypetlion    schedule 07.11.2018
comment
Как обобщить его для более чем 2 файлов?   -  person iOwais    schedule 07.11.2018


Ответы (3)


Изменить: вот более общий способ сделать это для любого списка файлов (пояснение в комментариях):

f1=open('file1.txt','r') #file 1
f2=open('file2.txt','r') #file 2

file_list = [f1, f2] # This would hold all your open files
num_files = len(file_list)

frequencies = {} # We'll just make one dictionary to hold the frequencies

for i, f in enumerate(file_list): # Loop over the files, keeping an index i
    for line in f: # Get the lines of that file
        for word in line.split(): # Get the words of that file
            if not word in frequencies:
                frequencies[word] = [0 for _ in range(num_files)] # make a list of 0's for any word you haven't seen yet -- one 0 for each file

            frequencies[word][i] += 1 # Increment the frequency count for that word and file

print frequencies

Следуя коду, который вы написали, вот как вы можете создать комбинированный словарь:

import operator
f1=open('file1.txt','r') #file 1
f2=open('file2.txt','r') #file 2

wordlist=[]
wordlist2=[]
for line in f1:
    for word in line.split():
        wordlist.append(word)

for line in f2:
    for word in line.split():
        wordlist2.append(word)

worddictionary = {}
for word in wordlist:
    if word in worddictionary:
        worddictionary[word] += 1
    else:
        worddictionary[word] = 1

worddictionary2 = {}
for word in wordlist2:
    if word in worddictionary2:
        worddictionary2[word] += 1
    else:
        worddictionary2[word] = 1

# Create a combined dictionary
combined_dictionary = {}
all_word_set = set(worddictionary.keys()) | set(worddictionary2.keys())
for word in all_word_set:
    combined_dictionary[word] = [0,0]
    if word in worddictionary:
        combined_dictionary[word][0] = worddictionary[word]
    if word in worddictionary2:
        combined_dictionary[word][1] = worddictionary2[word]


print(worddictionary)
print(worddictionary2)
print(combined_dictionary)
person killian95    schedule 07.11.2018
comment
Большое спасибо, есть ли способ, которым я могу обобщить это? на данный момент это будет работать только для 2 файлов, но что, если мне нужно сравнить более 2? - person iOwais; 07.11.2018
comment
Определенно. Чуть позже я опубликую более общий подход. - person killian95; 07.11.2018
comment
и, пожалуйста, не могли бы вы добавить к нему некоторые пояснения? это будет очень полезно для меня - person iOwais; 07.11.2018
comment
Поскольку я новичок в переполнении стека, я просто проверял его функции. Я прошу прощения - person iOwais; 13.11.2018

Изменить: я неправильно понял проблему, код теперь работает для вашего вопроса.

f1 = open('file1.txt','r') #file 1
f2 = open('file2.txt','r') #file 2

wordList = {}

for line in f1.readlines(): #for each line in lines (file.readlines() returns a list)
    for word in line.split(): #for each word in each line
        if(not word in wordList): #if the word is not already in our dictionary
            wordList[word] = 0 #Add the word to the dictionary

for line in f2.readlines(): #for each line in lines (file.readlines() returns a list)
    for word in line.split(): #for each word in each line
        if(word in wordList): #if the word is already in our dictionary
            wordList[word] = wordList[word]+1 #add one to it's value

f1.close() #close files
f2.close()

f1 = open('file1.txt','r') #Have to re-open because we are at the end of the file.
#might be a n easier way of doing this

for line in f1.readlines(): #Removing keys whose values are 0
    for word in line.split(): #for each word in each line
        try:
            if(wordList[word] == 0): #if it's value is 0
                del wordList[word] #remove it from the dictionary
            else:
                wordList[word] = wordList[word]+1 #if it's value is not 0, add one to it for each occurrence in file1
        except:
            pass #we know the error was that there was no wordList[word]
f1.close()

print(wordList)

Добавление слов первого файла, если это слово находится во втором файле, добавьте к значению единицу. После этого проверьте каждое слово, если оно равно 0, удалите его.

Этого нельзя сделать, перебирая словарь, потому что он меняет размер при переборе.

Вот как вы могли бы реализовать это для нескольких файлов (более сложных):

f1 = open('file1.txt','r') #file 1
f2 = open('file2.txt','r') #file 2

fileList = ["file1.txt", "file2.txt"]
openList = []
for i in range(len(fileList)):
    openList.append(open(fileList[i], 'r'))

fileWords = []

for i, file in enumerate(openList): #for each file
    fileWords.append({}) #add a dictionary to our list
    for line in file: #for each line in each file
        for word in line.split(): #for each word in each line
            if(word in fileWords[i]): #if the word is already in our dictionary
                fileWords[i][word] += 1 #add one to it
            else:
                fileWords[i][word] = 1 #add it to our dictionary with value 0

for i in openList:
    i.close()

for i, wL in enumerate(fileWords):
    print(f"File: {fileList[i]}")
    for l in wL.items():
        print(l)
    #print(f"File {i}\n{wL}")
person Tom Martin    schedule 07.11.2018
comment
Пожалуйста, не могли бы вы объяснить это, но дальше? Я новичок в питоне, поэтому мне немного сложно понять - person iOwais; 07.11.2018
comment
спасибо, но это не работает. выдает KeyError в if(wordList[word] == 0) - person iOwais; 08.11.2018

Следующая демонстрационная программа может оказаться хорошей отправной точкой для получения частоты слов в ваших файлах:

#! /usr/bin/env python3
import collections
import pathlib
import pprint
import re
import sys


def main():
    freq = get_freq(sys.argv[0])
    pprint.pprint(freq)


def get_freq(path):
    if isinstance(path, str):
        path = pathlib.Path(path)
    return collections.Counter(
        match.group() for match in re.finditer(r'\b\w+\b', path.open().read())
    )


if __name__ == '__main__':
    main()

В частности, вы захотите использовать функцию get_freq, чтобы получить объект Counter, который сообщает вам, каковы частоты слов. Ваша программа может вызывать функцию get_freq несколько раз с разными именами файлов, и вы обнаружите, что объекты Counter очень похожи на словари, которые вы использовали ранее.

person Noctis Skytower    schedule 07.11.2018