新手问题 Ruby 对 csv 文件进行统计

ynopeeb · 2018年07月30日 · 最后由 ken 回复于 2018年08月06日 · 2249 次阅读

需求:有一个 test.csv 文件,格式如下:

关键字   问题ID    概要  优先级
ONLINE-30763t43 2139480 查询  重要
ONLINE-38784480 2149335 失败  重要
ONLINE-33765689 2141691 消费者 普通
ONLINE-38127341 2154990 无法  重要
ONLINE-31797797 2154503 订单  普通
ONLINE-37566180 2139727 选择  紧急
ONLINE-39804474 2156819 查询  重要

需求统计 优先级中重要,紧急,普通的数量

查看了文档 : https://ruby-doc.org/stdlib-2.5.1/libdoc/csv/rdoc/CSV.html#method-i-converters ,尝试如下:

CSV.foreach("test.csv", headers: true) do | row |
## how to count
end

如果只是统计数量的话,可以初始化一个 hash, { "重要": 0, "紧急": 0, "普通": 0 },然后读取每行之后,判断优先级是什么,累加起来

用 python 吧 pandas

require 'csv'

emergency = 0
normal = 0
important = 0

CSV.foreach('123.csv', headers: true) do |row|
  if row[3] == '重要'
    important += 1
  elsif row[3] == '普通'
    normal += 1
  elsif row[3] == '紧急'
    emergency += 1
  end
end

puts "重要:#{important}"
puts "普通:#{normal}"
puts "紧急:#{emergency}"

写法可能很累赘,其实不用 if-elsif-elsif ,改用

case
  when
  when
  when
end

或许更好

用 postgres 的 COPY 把 csv 导入到数据库,然后用 activerecord,count 一下。数据量大时处理速度应该会比直接读 csv 快。

不考虑数据量问题的话,就一个简单的 reduce:

require 'csv'

CSV.foreach("data.csv", headers: true).reduce({}) do |acc, row|
  priority = row["优先级"]
  acc[priority] = (acc[priority] || 0) + 1
  acc
end

如果量大并且需要跟其他表结合做统计,导入数据库是更合适的选择。除了用 COPYForeign Data Wrapper 也可以考虑,简单粗暴。

数据库应该做的事情,别考虑 rails 了。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号