【问题标题】:Consolidate csv data in ruby to get totals/sums of unique values合并 ruby​​ 中的 csv 数据以获取唯一值的总数/总和
【发布时间】:2014-09-27 01:36:52
【问题描述】:

我仍在为一个基本问题苦苦挣扎,我在网上找不到答案。

我正在获取类似 CSV 的数据作为名称和数量:

Foo, 1.5
Bar, 1.2
Foo, 1.1
...

并希望将其合并为唯一名称,并将总数作为新值:

Foo, 2.6   #total of both Foo lines
Bar, 1.2
...

每次的数据集都不大,但任务却相当重复。

我尝试将其转换为哈希数组,找到uniq 名称,然后使用inject,但不知何故它变得相当复杂并且不起作用。此外,循环遍历所有内容似乎不是理想的方法。

有没有人有我想念的好主意或解决方案? (我只为 PHP 找到了“Extract value from row in csv and sum it”。)

【问题讨论】:

  • 展示您解决问题的尝试很重要。实际上,您似乎希望有人为您工作。

标签: ruby csv


【解决方案1】:

首先,您可以使用 Ruby 的 CSV 库来解析和转换您的 CSV 数据:

require 'csv'

csv_data = "Foo, 1.5\nBar, 1.2\nFoo, 1.1"

data_array = CSV.parse(csv_data, converters: :numeric)
#=> [["Foo", 1.5], ["Bar", 1.2], ["Foo", 1.1]]

为了对这些值求和,我将使用散列和 each_with_object

data_array.each_with_object(Hash.new(0)) { |(k, v), h| h[k] += v }
#=> {"Foo"=>2.6, "Bar"=>1.2}

【讨论】:

  • 非常好的解决方案...每个答案都已将 csv 数据视为一个数组..但是您首先解析它以将其转换为数组..这实际上是正确的 1+
  • 非常感谢,这绝对是完美的,就像一个魅力!比我摆弄的效率高得多... :)
  • @GaganGami 并不是每个答案都这么认为! ;)
【解决方案2】:

0.0 作为您的哈希帐户的default 选项很好地传递给每个项目的第一次出现:

input = [ ['Foo', 1.5],
          ['Bar', 1.2],
          ['Foo', 1.1] ]

result = input.inject(Hash.new(0.0)) do |sum, (key, value)|
  sum[key] += value
  sum
end

p result

【讨论】:

    【解决方案3】:

    哈希数组似乎是最简单的方法:

    假设:

    CSV=[["foo",1.5],["bar",2.2],["foo",1.1]]
    

    只要做:

    myCSV=[["foo",1.5],["bar",1.2],["foo",1.1]]
    myCSV.each_with_object(Hash.new(0.0)){|row,sum| sum[row[0]]+=row[1]}
    => {
      "foo" => 2.6,
      "bar" => 1.2
    }
    

    如果您是从文件中读取,使用 CSV 库或多或少是一样的:

    sum=Hash.new(0.0)
    CSV.foreach("path/to/file.csv") do |row|
      sum[row[0]]+=row[1]
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-06-09
      • 1970-01-01
      • 2016-04-01
      • 2012-11-02
      • 1970-01-01
      • 2013-10-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多