繁体   English   中英

如何计算段落中特定单词的实例数?

[英]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, ...}

如果使用以下命令,则可能会更短且更易于阅读:

  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

请注意,这是区分大小写的,但如果您想要不区分大小写,那么这是一个小调整。

计算一个单词在文本中出现的次数:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM