2011-12-16 7 views
1

Я хотел бы подсчитать количество раз, когда набор слов появляется в каждом абзаце в текстовом файле. Я могу подсчитать количество раз, когда набор слов появляется во всем тексте.Как подсчитать количество экземпляров конкретных слов в абзаце?

Мне было предложено, чтобы мой код был действительно неисправен, поэтому я просто спрошу, что я хотел бы сделать, и если вы хотите, вы можете посмотреть на код, который у меня внизу.

Итак, учитывая, что в «frequency_count.txt» есть слова «яблочная груша», я хочу знать, как часто «яблоко» появляется в каждом абзаце отдельного файла «test_essay.txt», как часто появляется груша и т. д., а затем для того, чтобы эти числа были распечатаны в серии строк чисел, каждый из которых соответствует абзацу.

Например:

apple, pear, grape, melon, kiwi 
3,5,2,7,8 
2,3,1,6,7 
5,6,8,2,3 

Где каждая строка соответствует одному из пунктов.

Я очень, очень новый для Руби, так что спасибо за ваше терпение.

output_file = '/Users/yirenlu/Quora-Personal-Analytics/weka_input6.csv' 
o = File.open(output_file, "r+") 

common_words = '/Users/yirenlu/Quora-Personal-Analytics/frequency_count.txt' 
c = File.open(common_words, "r") 

c.each_line{|$line1| 
    words1 = $line1.split 
    words1.each{|w1| 
     the_file = '/Users/yirenlu/Quora-Personal-Analytics/test_essay.txt' 
     f = File.open(the_file, "r") 
     rows = File.readlines("/Users/yirenlu/Quora-Personal-Analytics/test_essay.txt") 
     text = rows.join 
     paragraph = text.split(/\n\n/) 
     paragraph.each{|p| 
      h = Hash.new 
      puts "this is each paragraph" 
      p.each_line{|line| 
       puts "this is each line" 
       words = line.split 
       words.each{|w| 
        if w1 == w 
         if h.has_key?(w) 
          h[w1] = h[w1] + 1 
         else 
          h[w1] = 1 
         end 
         $x = h[w1] 
        end 
       } 
      } 
      o.print "#{$x}," 
     } 
    } 
    o.print "\n" 
    o.print "#{$line1}" 
} 
+2

Я бы предположил, что использование более описательных имен переменных и последовательных отступов (особенно для блоков) поставит вопрос намного легче ответить. Вы даже можете найти ошибку самостоятельно! –

+0

Вы не «в основном там» вообще. Я попытался улучшить ваш код, но выясняется, что проблема заключается не только в обработке хэша. В коде, который вы опубликовали, есть всевозможные ошибки. Как отмечает Палмер, вы даже не делаете последовательных отступов, поэтому люди не захотят читать ваш код. Легче выкинуть свой код и спросить кого-то, что вы хотите сделать. – sawa

+0

Это домашнее задание? –

ответ

0

Вот альтернативный ответ, который был изменен для краткости (хотя не так легко читать, как мой другой ответ).

require 'csv' 

words = %w(apple pear grape melon kiwi) 
text = File.open("test_essay.txt").read 

CSV.open("file.csv", "wb") do |csv| 
    text.split(/\n\n/).map {|p| csv << words.map {|w| p.scan(/\b#{w}\b/).length}} 
end 

Я предпочитаю немного более длинный, но более самодокументирующий код, но это интересно видеть, насколько он может получить.

0

Чтобы подсчитать, сколько раз появляется одно слово в тексте:

text = "word aaa word word word bbb ccc ccc" 
text.scan(/\w+/).count("word") # => 4 

подсчитывать набор слов:

text = "word aaa word word word bbb ccc ccc" 
wlist = text.scan(/\w+/) 
wset = ["word", "ccc"] 
result = {} 
wset.each {|word| result[word] = wlist.count(word) } 
result # => {"word" => 4, "ccc" => 2} 
result["ccc"] # => 2 
+1

Вы уверены, что 'результат << wlist.count (word)' работает? Как «результат» получает информацию о ключе? – sawa

+0

@sawa как я его оставил ??? Спасибо, исправлено. –

1

Если вы привыкли к PHP или Perl вас может показаться, что переменная типа $line1 является локальной, но это глобальная. Их использование сильно обескуражено, и количество случаев, когда они строго необходимы, очень невелико. В большинстве случаев вы можете просто опустить $ и использовать переменные таким образом с правильной областью охвата.

Этот пример также содержит почти нечитаемый отступ, хотя, возможно, это был артефакт процедуры вырезания и вставки.

Вообще то, что вы хотите для счетчиков, чтобы создать хэш со значением по умолчанию, равным нулю, а затем добавить к тому, что в соответствии с требованиями:

# Create a hash where the default values for each key is 0 
counter = Hash.new(0) 

# Add to the counters where required 
counter['foo'] += 1 
counter['bar'] += 2 

puts counter['foo'] 
# => 1 
puts counter['baz'] 
# => 0 

Вы в основном есть то, что вам нужно, но все это все запутано и просто нужно чтобы быть лучше организованы.

1

Ниже приведены два однострочных числа для расчета частот слов в строке.

Первый немного легче понять, но это менее эффективно:

txt.scan(/\w+/).group_by{|word| word.downcase}.map{|k,v| [k, v.size]} 
# => [['word1', 1], ['word2', 5], ...] 

Второе решение:

txt.scan(/\w+/).inject(Hash.new(0)) { |hash, w| hash[w.downcase] += 1; hash} 
# => {'word1' => 1, 'word2' => 5, ...} 
+0

+1 Во-первых, как я это сделаю. –

0

Что об этом:

# Create an array of regexes to be used in `scan' in the loop. 
# `\b' makes sure that `barfoobar' does not match `bar' or `foo'. 
p word_list = File.open("frequency_count.txt"){|io| io.read.scan(/\w+/)}.map{|w| /\b#{w}\b/} 
File.open("test_essay.txt") do |io| 
    loop do 
     # Add lines to `paragraph' as long as there is a continuous line 
     paragraph = "" 
     # A `l.chomp.empty?' becomes true at paragraph border 
     while l = io.gets and !l.chomp.empty? 
      paragraph << l 
     end 
     p word_list.map{|re| paragraph.scan(re).length} 
     # The end of file has been reached when `l == nil' 
     break unless l 
    end 
end 
1

Это может быть короче и легче читать, если вы используете:

  1. CSV-библиотека.
  2. Более функциональный подход с использованием карты и блоков.
require 'csv' 

common_words = %w(apple pear grape melon kiwi) 
text = File.open("test_essay.txt").read 

def word_frequency(words, text) 
    words.map { |word| text.scan(/\b#{word}\b/).length } 
end 

CSV.open("file.csv", "wb") do |csv| 
    paragraphs = text.split /\n\n/ 
    paragraphs.each do |para| 
    csv << word_frequency(common_words, para) 
    end 
end 

Примечание это в настоящее время чувствительны к регистру, но это небольшая корректировка, если вы хотите прецедентное нечувствительность.

+0

Ах, я не понимал, что есть библиотека csv. Это именно то, что мне нужно. Благодаря! –

+0

Вы хотите принять этот ответ? (и проголосуйте за любые полезные ответы тоже) –

Смежные вопросы