Mar*_*cos 27 ruby csv arrays hash stocks
也许有人可以帮助我.
从像这样的CSV文件开始:
Ticker,"Price","Market Cap"
ZUMZ,30.00,933.90
XTEX,16.02,811.57
AAC,9.83,80.02
Run Code Online (Sandbox Code Playgroud)
我设法把它们读成一个数组:
require 'csv'
tickers = CSV.read("stocks.csv", {:headers => true, :return_headers => true, :header_converters => :symbol, :converters => :all} )
Run Code Online (Sandbox Code Playgroud)
要验证数据,这有效:
puts tickers[1][:ticker]
ZUMZ
Run Code Online (Sandbox Code Playgroud)
但是,这不是:
puts tickers[:ticker => "XTEX"][:price]
Run Code Online (Sandbox Code Playgroud)
如何使用自动收录器字段作为唯一键将此数组转换为哈希值,以便我可以轻松地按照输入的第1行中的定义查找任何其他字段?处理更多的列和行.
非常感激!
Mic*_*ohl 33
像这样(它也适用于其他CSV,而不仅仅是你指定的那个):
require 'csv'
tickers = {}
CSV.foreach("stocks.csv", :headers => true, :header_converters => :symbol, :converters => :all) do |row|
tickers[row.fields[0]] = Hash[row.headers[1..-1].zip(row.fields[1..-1])]
end
Run Code Online (Sandbox Code Playgroud)
结果:
{"ZUMZ"=>{:price=>30.0, :market_cap=>933.9}, "XTEX"=>{:price=>16.02, :market_cap=>811.57}, "AAC"=>{:price=>9.83, :market_cap=>80.02}}
Run Code Online (Sandbox Code Playgroud)
您可以像这样访问此数据结构中的元素:
puts tickers["XTEX"][:price] #=> 16.02
Run Code Online (Sandbox Code Playgroud)
编辑(根据评论):为了选择元素,你可以做类似的事情
tickers.select { |ticker, vals| vals[:price] > 10.0 }
Run Code Online (Sandbox Code Playgroud)
CSV.read(file_path, headers:true, header_converters: :symbol, converters: :all).collect do |row|
Hash[row.collect { |c,r| [c,r] }]
end
Run Code Online (Sandbox Code Playgroud)
为了获得两全其美的效果(从大文件中快速读取以及本机 Ruby CSV 对象的好处),我的代码后来演变成了这种方法:
$stock="XTEX"
csv_data = CSV.parse IO.read(%`|sed -n "1p; /^#{$stock},/p" stocks.csv`), {:headers => true, :return_headers => false, :header_converters => :symbol, :converters => :all}
# Now the 1-row CSV object is ready for use, eg:
$company = csv_data[:company][0]
$volatility_month = csv_data[:volatility_month][0].to_f
$sector = csv_data[:sector][0]
$industry = csv_data[:industry][0]
$rsi14d = csv_data[:relative_strength_index_14][0].to_f
Run Code Online (Sandbox Code Playgroud)
这更接近我原来的方法,但只读取一条记录加上包含标题的输入 csv 文件的第 1 行。内联sed
指令可以解决这个问题——而且整个过程非常即时。这比上一个更好,因为现在我可以从 Ruby 访问所有字段,并且可以关联地访问,不再像awk
.