Извлечение элементов из n-строчных блоков в файл, подсчет частоты элементов для каждого блока, Python

1

У меня есть текстовый файл, содержащий 5-строчные фрагменты строк с разделителями табуляции:

 1 \t DESCRIPTION \t SENTENCE \t ITEMS

 1 \t DESCRIPTION \t SENTENCE \t ITEMS

 1 \t DESCRIPTION \t SENTENCE \t ITEMS

 1 \t DESCRIPTION \t SENTENCE \t ITEMS

 1 \t DESCRIPTION \t SENTENCE \t ITEMS

 2 \t DESCRIPTION \t SENTENCE \t ITEMS

 2 \t DESCRIPTION \t SENTENCE \t ITEMS

 2 \t DESCRIPTION \t SENTENCE \t ITEMS

 2 \t DESCRIPTION \t SENTENCE \t ITEMS

 2 \t DESCRIPTION \t SENTENCE \t ITEMS

и т.п.

В каждом фрагменте колонки DESCRIPTION и SENTENCE одинаковы. Данные, представляющие интерес, находятся в столбце ITEMS, который отличается для каждой строки в куске и имеет следующий формат:

word1, word2, word3

...и так далее

Для каждого 5-строчного фрагмента мне нужно подсчитать частоту слов1, word2 и т.д. В ITEMS. Например, если первый 5-строчный кусок был следующим

 1 \t DESCRIPTION \t SENTENCE \t word1, word2, word3

 1 \t DESCRIPTION \t SENTENCE \t word1, word2

 1 \t DESCRIPTION \t SENTENCE \t word4

 1 \t DESCRIPTION \t SENTENCE \t word1, word2, word3

 1 \t DESCRIPTION \t SENTENCE \t word1, word2

то правильный вывод для этого 5-строчного фрагмента будет

1, SENTENCE, (word1: 4, word2: 4, word3: 2, word4: 1)

То есть номер куска, за которым следует предложение, за которым следуют частоты для слов.

У меня есть код для извлечения пятистрочных фрагментов и подсчета частоты слов в куске после его извлечения, но я застрял на задаче изолировать каждый кусок, получить частоты слов, перейти к следующему и т.д.

from itertools import groupby 

def GetFrequencies(file):
    file_contents = open(file).readlines()  #file as list
    """use zip to get the entire file as list of 5-line chunk tuples""" 
    five_line_increments = zip(*[iter(file_contents)]*5) 
    for chunk in five_line_increments:  #for each 5-line chunk... 
        for sentence in chunk:          #...and for each sentence in that chunk
            words = sentence.split('\t')[3].split() #get the ITEMS column at index 3
            words_no_comma = [x.strip(',') for x in words]  #get rid of the commas
            words_no_ws = [x.strip(' ')for x in words_no_comma] #get rid of the whitespace resulting from the removed commas


       """STUCK HERE   The idea originally was to take the words lists for 
       each chunk and combine them to create a big list, 'collection,' and
       feed this into the for-loop below."""





    for key, group in groupby(collection): #collection is a big list containing all of the words in the ITEMS section of the chunk, e.g, ['word1', 'word2', word3', 'word1', 'word1', 'word2', etc.]
        print key,len(list(group)),    
Теги:
text-processing

4 ответа

0
Лучший ответ

Немного изменил ваш код, я думаю, он делает то, что вы хотите:

file_contents = open(file).readlines()  #file as list
"""use zip to get the entire file as list of 5-line chunk tuples""" 
five_line_increments = zip(*[iter(file_contents)]*5) 
for chunk in five_line_increments:  #for each 5-line chunk...
    word_freq = {} #word frequencies for each chunk
    for sentence in chunk:          #...and for each sentence in that chunk
        words = "".join(sentence.split('\t')[3]).strip('\n').split(', ') #get the ITEMS column at index 3 and put them in list
        for word in words:
            if word not in word_freq:
                word_freq[word] = 1
            else:
                word_freq[word] += 1


    print word_freq

Вывод:

{'word4': 1, 'word1': 4, 'word3': 2, 'word2': 4}
  • 0
    Это делает работу. Спасибо!
1

В стандартной библиотеке есть синтаксический анализатор csv, который может обрабатывать входное расщепление для вас

import csv
import collections

def GetFrequencies(file_in):
    sentences = dict()
    with csv.reader(open(file_in, 'rb'), delimiter='\t') as csv_file:
        for line in csv_file:
            sentence = line[0]
            if sentence not in sentences:
                sentences[sentence] = collections.Counter()
            sentences[sentence].update([x.strip(' ') for x in line[3].split(',')])
1

Использование python 2.7

#!/usr/bin/env python

import collections

chunks={}

with open('input') as fd:
    for line in fd:
        line=line.split()
        if not line:
            continue
        if chunks.has_key(line[0]):
            for i in line[3:]:
                chunks[line[0]].append(i.replace(',',''))
        else:
            chunks[line[0]]=[line[2]]

for k,v in chunks.iteritems():
    counter=collections.Counter(v[1:])
    print k, v[0], counter

Выходы:

1 SENTENCE Counter({'word1': 3, 'word2': 3, 'word4': 1, 'word3': 1})
  • 0
    Невозможно обновить до 2.7, так как есть время, но это хороший код
0

Подводя итог: вы хотите добавить все "слова" в коллекцию, если они не "ОПИСАНИЕ" или "ПРИЧИН"? Попробуй это:

for word in words_no_ws:
    if word not in ("DESCRIPTION", "SENTENCE"):
        collection.append(word)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню