[英]How do I count the number of instances of particular words in a paragraph?
我想計算一組單詞出現在文本文件中每個段落中的次數。 我能夠計算一組單詞在整個文本中出現的次數。
有人向我建議我的代碼確實有問題,所以我只想問問我想做什么,如果需要,可以看一下底部的代碼。
因此,鑒於“ frequency_count.txt”中包含“ apple pear grape melon kiwi”一詞,我想知道“ apple”在單獨文件“ test_essay.txt”的每個段落中出現的頻率,梨顯示的頻率等等,然后將這些數字打印成一系列數字,每行對應一個段落。
例如:
apple, pear, grape, melon, kiwi
3,5,2,7,8
2,3,1,6,7
5,6,8,2,3
每行對應一個段落。
我對Ruby非常非常新,所以感謝您的耐心等待。
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}"
}
如果您習慣使用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
您基本上擁有了所需的東西,但是所有的東西都是混亂的,只需要更好地組織即可。
這是兩個單線計算字符串中單詞的頻率。
第一個比較容易理解,但是效果較差:
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, ...}
如果使用以下命令,則可能會更短且更易於閱讀:
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
請注意,這是區分大小寫的,但如果您想要不區分大小寫,那么這是一個小調整。
計算一個單詞在文本中出現的次數:
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
那這個呢:
# 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
這是一個替代答案,為了簡潔而進行了調整(盡管不像我的其他答案那樣容易閱讀)。
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
我更喜歡稍長但更自我記錄的代碼,但看到它有多小可能很有趣。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.