【问题标题】:Ignoring multiple header lines in a CSV忽略 CSV 中的多个标题行
【发布时间】:2014-10-19 17:54:10
【问题描述】:

我对 Ruby 的 CSV 模块做了一些工作,但在让它忽略多个标题行时遇到了一些问题。

具体来说,这里是我要解析的文件的前二十行:

USGS Digital Spectral Library splib06a
Clark and others 2007, USGS, Data Series 231.

For further information on spectrsocopy, see: http://speclab.cr.usgs.gov

ASCII Spectral Data file contents:
line 15 title
line 16 history
line 17 to end:  3-columns of data:
     wavelength    reflectance    standard deviation

(standard deviation of 0.000000 means not measured)
(      -1.23e34  indicates a deleted number)
----------------------------------------------------
Olivine GDS70.a Fo89 165um   W1R1Bb AREF
copy of splib05a r 5038
       0.205100      -1.23e34        0.090781
       0.213100      -1.23e34        0.018820
       0.221100      -1.23e34        0.005416
       0.229100      -1.23e34        0.002928

第 10 行给出实际的标题,第 17 行是实际数据的开始位置。

这是我的代码:

require "nyaplot"

# Note that DataFrame basically just inherits from Ruby's CSV module.
class SpectraHelper < Nyaplot::DataFrame
  class << self
    def from_csv filename
      df = super(filename, col_sep: ' ') do |csv|
        csv.convert do |field, info|
          STDERR.puts "Field is #{field}"
        end
      end
    end
  end

  def csv_headers
    [:wavelength, :reflectance, :standard_deviation]
  end
end


def read_asc filename
  f = File.open(filename, "r")
  16.times do
    line = f.gets
    puts "Ignoring #{line}"
  end

  d = SpectraHelper.from_csv(f)
end

输出表明我对f.gets 的调用实际上并没有忽略这些行,我不明白为什么。以下是输出的前几行:

Field is Clark
Field is and
Field is others
Field is 2007,
Field is USGS,

我尝试寻找显示处理更复杂 CSV 文件的教程或示例,但运气不佳。如果有人可以向我指出一个可以回答这个问题的资源,我将不胜感激(并且更愿意将其标记为已接受,而不是针对我的特定问题的解决方案——但两者都将不胜感激)。

使用 Ruby 2.1。

【问题讨论】:

    标签: ruby csv


    【解决方案1】:

    它认为您使用的是::open,它使用的是IO.open。此方法将再次打开文件。

    我稍微修改了脚本

    require 'csv'
    
    class SpectraHelper < CSV
      def self.from_csv(filename)
        df = open(filename, 'r' , col_sep: ' ') do |csv|
          csv.drop(16).each {|c| p c}
        end
      end
    end
    
    def read_asc(filename)
      SpectraHelper.from_csv(filename)
    end
    
    read_asc "data/csv1.csv"
    

    【讨论】:

    • 您在哪里找到drop 方法?我在文档中没有看到它。
    • @mohawkjohn 以这种方式打开的文件是一个 IO 对象,其中包括 Enumerable 模块。
    【解决方案2】:

    原来问题不在于我对 CSV 的理解,而在于现在 Nyaplot::DataFrame 处理 CSV 文件。

    基本上,Nyaplot 实际上并不将内容存储为 CSV。 CSV 只是一种中间格式。因此,处理文件的一种简单方法是利用@khelli 的建议:

    def read_asc filename
      Nyaplot::DataFrame.new(CSV.open(filename, 'r',
         col_sep: ' ',
         headers: [:wavelength, :reflectance, :standard_deviation],
         converters: :numeric).
       drop(16).
       map do |csv_row|
        csv_row.to_h.delete_if { |k,v| k.nil? }
      end)
    end
    

    谢谢大家的建议。

    【讨论】:

      【解决方案3】:

      我不会使用 CSV 模块,因为您的文件格式不正确。以下代码将读取文件并为您提供记录数组:

        lines = File.open(filename,'r').readlines
        lines.slice!(0,16)
        records = lines.map {|line| line.chomp.split}
      

      records输出:

      [["0.205100", "-1.23e34", "0.090781"], ["0.213100", "-1.23e34", "0.018820"], ["0.221100", "-1.23e34", "0.005416"], ["0.229100", "-1.23e34", "0.002928"]]
      

      【讨论】:

      • 这实际上不是我所提问题的答案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-12-01
      • 1970-01-01
      • 2014-05-08
      • 2023-03-24
      • 1970-01-01
      • 2016-06-18
      • 1970-01-01
      相关资源
      最近更新 更多