总和矩阵为数字而不是字符串ruby

时间:2017-11-21 18:05:19

标签: ruby csv matrix

我想从CSV文件中总结2个矩阵 目前,我将它们放入数组中,然后将数组转换为矩阵。但是,当我打印它们时,我会得到连接的字符串而不是求和的整数。

require 'csv'
require 'matrix'

matrix1 = "./matrix1.csv"
matrix2 = "./matrix2.csv"

line_count = 0
elements_in_line_count = 0
arr1 = Array.new    #=> []
arr2 = Array.new    #=> []

CSV.foreach(matrix1) do |row|
  arr1 << row
  line_count += 1
  elements_in_line_count =  row.size
end

n1 = elements_in_line_count
m1 = line_count 

# find n and m of second matrix 

line_count = 0
elements_in_line_count = 0

CSV.foreach(matrix2) do |row|
 # print row
   arr2 << row
  line_count += 1
  elements_in_line_count =  row.size
end

puts Matrix.rows(arr1) + Matrix.rows(arr2)

例如,CSV 1为:

  1,2
  3,4

CSV 2相同。 输出是

Matrix[[11, 22], [33, 44]]

但我希望它是[2,4],[6,8]

4 个答案:

答案 0 :(得分:3)

当您读入CSV时,默认情况下它会将所有行/列作为字符串读入,Ruby CSV类可以将可选参数带到foreachnew以及类似名为:converters的方法,用于转换每个适用的列。它可以采用的转换器之一是

  

:整数

     

转换Integer()接受的任何字段。

因此,您还可以将代码更改为:

csv_options = { converters: [:integer] }
CSV.foreach(matrix1, csv_options) do |row|
# ...
CSV.foreach(matrix2, csv_options) do |row|

获得与每行调用map(&:to_i)类似的结果。

答案 1 :(得分:2)

[m1, m2].map do |m|
  CSV.foreach(m).map { |row| row.map(&:to_i) }
end.reduce do |m1, m2|
  m1.map.with_index do |row, idx|
    row.zip(m2[idx]).map { |cell1, cell2| cell1 + cell2 }
  end
end

答案 2 :(得分:1)

当您在CSV中阅读时,所有列都将成为字符串,因此您必须手动转换为代码中的数字。

如果CSV的所有列都是数字,您可以将.map(&:to_i)添加到行行。像这样:

CSV.foreach(matrix1) do |row|
  arr1 << row.map(&:to_i) # <-- this will turn everything in the row into a number
  line_count += 1
  elements_in_line_count =  row.size
end

答案 3 :(得分:1)

如果要添加矩阵,请考虑使用Ruby的内置Matrix类,特别是实例方法Matrix#+

让我们先构建三个CSV文件。

fname1 = 't1.csv'
fname2 = 't2.csv'
fname3 = 't3.csv'

File.write(fname1, "1,2\n3,4")
  #=> 7
File.write(fname2, "100,200\n300,400")
  #=> 15
File.write(fname3, "1000,2000\n3000,4000")
  #=> 19

我们可以将基础矩阵求和如下。

require 'csv'
require 'matrix'

fnames = [fname1, fname2, fname3]

fnames.drop(1).reduce(matrix_from_CSV(fnames.first)) do |t,fname|
  t + matrix_from_CSV(fname)
end.to_a
  #=> [[1101, 2202],
  #    [3303, 4404]]

def matrix_from_CSV(fname)
  Matrix[*CSV.read(fname, converters: [:integer])]
end

我从@ Simple的回答中借用converters: [:integer]。我没有意识到这一点。