Ruby CSV:比较列(来自两个 csvs),将新列写入一个
Ruby CSV: Comparison of columns (from two csvs), write new column in one
我已经搜索过,但没有找到解决这个特定难题的方法。我有两个有时与同一事物相关的 CSV 数据文件。这是一个例子:
CSV1(500 行):
date,reference,amount,type
10/13/2015,,1510.40,sale
10/13/2015,,312.90,sale
10/14/2015,,928.50,sale
10/15/2015,,820.25,sale
10/12/2015,,702.70,credit
CSV2(20000 行):
reference,date,amount
243534985,10/13/2015,312.90
345893745,10/15/2015,820.25
086234523,10/14/2015,928.50
458235832,10/13/2015,1510.40
我的目标是将 CSV2 中的日期和金额与 CSV1 中的日期和金额相匹配,并将 CSV2 中的引用写入相应行中的引用列。
这是一个简化的视图,因为 CSV2 实际上包含更多的列 - 这些只是相关的列,所以理想情况下我想通过 header 名称或索引来引用它们?
这是我尝试过的方法,但我有点卡住了。
require 'csv'
data1 = {}
data2 = {}
CSV.foreach("data1.csv", :headers => true, :header_converters => :symbol, :converters => :all) do |row|
data1[row.fields[0]] = Hash[row.headers[1..-1].zip(row.fields[1..-1])]
end
CSV.foreach("data2.csv", :headers => true, :header_converters => :symbol, :converters => :all) do |row|
data2[row.fields[0]] = Hash[row.headers[1..-1].zip(row.fields[1..-1])]
end
data1.each do |data1_row|
data2.each do |data2_row|
if (data1_row['comparitive'] == data2_row['comparitive'])
puts data1_row['identifier'] + data2_row['column_thats_important_and_wanted']
end
end
end
结果:
22:in `[]': no implicit conversion of String into Integer (TypeError)
我也试过:
CSV.foreach('data2.csv') do |data2|
CSV.foreach('data1.csv') do |data1|
if (data1[3] == data2[4])
data1[1] << data2[1]
puts "Change made!"
else
puts "nothing changed."
end
end
end
然而,这与 if 语句中的任何内容都不匹配,所以可能不是正确的方法?
headers 方法应该可以帮助您匹配列——从那里开始,就是解析修改后的数据并将修改后的数据写回文件。
已解决。
data1 = CSV.read('data1.csv')
data2 = CSV.read('data2.csv')
data2.each do |data2|
data1.each do |data1|
if (data1[5] == data2[4])
data1[1] = data2[1]
puts "Change made!"
puts data1
end
end
end
File.open('referenced.csv','w'){ |f| f << data1.map(&:to_csv).join("")}
我已经搜索过,但没有找到解决这个特定难题的方法。我有两个有时与同一事物相关的 CSV 数据文件。这是一个例子:
CSV1(500 行):
date,reference,amount,type
10/13/2015,,1510.40,sale
10/13/2015,,312.90,sale
10/14/2015,,928.50,sale
10/15/2015,,820.25,sale
10/12/2015,,702.70,credit
CSV2(20000 行):
reference,date,amount
243534985,10/13/2015,312.90
345893745,10/15/2015,820.25
086234523,10/14/2015,928.50
458235832,10/13/2015,1510.40
我的目标是将 CSV2 中的日期和金额与 CSV1 中的日期和金额相匹配,并将 CSV2 中的引用写入相应行中的引用列。
这是一个简化的视图,因为 CSV2 实际上包含更多的列 - 这些只是相关的列,所以理想情况下我想通过 header 名称或索引来引用它们?
这是我尝试过的方法,但我有点卡住了。
require 'csv'
data1 = {}
data2 = {}
CSV.foreach("data1.csv", :headers => true, :header_converters => :symbol, :converters => :all) do |row|
data1[row.fields[0]] = Hash[row.headers[1..-1].zip(row.fields[1..-1])]
end
CSV.foreach("data2.csv", :headers => true, :header_converters => :symbol, :converters => :all) do |row|
data2[row.fields[0]] = Hash[row.headers[1..-1].zip(row.fields[1..-1])]
end
data1.each do |data1_row|
data2.each do |data2_row|
if (data1_row['comparitive'] == data2_row['comparitive'])
puts data1_row['identifier'] + data2_row['column_thats_important_and_wanted']
end
end
end
结果:
22:in `[]': no implicit conversion of String into Integer (TypeError)
我也试过:
CSV.foreach('data2.csv') do |data2|
CSV.foreach('data1.csv') do |data1|
if (data1[3] == data2[4])
data1[1] << data2[1]
puts "Change made!"
else
puts "nothing changed."
end
end
end
然而,这与 if 语句中的任何内容都不匹配,所以可能不是正确的方法?
headers 方法应该可以帮助您匹配列——从那里开始,就是解析修改后的数据并将修改后的数据写回文件。
已解决。
data1 = CSV.read('data1.csv')
data2 = CSV.read('data2.csv')
data2.each do |data2|
data1.each do |data1|
if (data1[5] == data2[4])
data1[1] = data2[1]
puts "Change made!"
puts data1
end
end
end
File.open('referenced.csv','w'){ |f| f << data1.map(&:to_csv).join("")}