忽略CSV中的多个标题行

问题描述:

我已经使用Ruby的CSV模块做了一些工作,但在忽略多个标题行时遇到了一些问题。忽略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 

实际的头是在第十行给出,和第十七行是实际数据开始。

这里是我的代码:

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。

原来这里的问题是不是与我的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 

谢谢大家,您的建议。

它相信你正在使用::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" 
+0

你从哪里找到“drop”方法?我没有在文档中看到它。 – 2014-10-19 19:56:21

+1

@mohawkjohn以这种方式打开的文件是一个IO对象,其中包含Enumerable模块。 – steenslag 2014-10-19 21:52:37

+0

@mohawkjohn是正确的:http://ruby-doc.org/stdlib-2.1.2/libdoc/csv/rdoc/CSV.html – khelll 2014-10-19 22:01:05

我不会使用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"]] 
+0

这实际上不是我问的问题的答案。 – 2014-10-19 20:03:08