2017-03-06 37 views
0

我從CSV文件解析棒球統計數據,我需要考慮一個賽季內爲多支球隊效力的球員。目前我的代碼看起來是這樣的:如何結合使用Ruby從CSV解析的類似字段

require 'CSV' 

CSV.foreach("Batting-07-12-resaved.csv",{:headers=>:first_row}) do |row| 
    if row[7].to_i != 0 && row[5] != 0 && row[1].to_i == 2009 
     avg = row[7].to_f/row[5].to_f 
     puts row[0] + ": " + avg.round(3).to_s[1..-1] 
    end 
end 

的CSV頭這個樣子,而且球員被排序的,看起來像他們的名字和可能復發基礎上,他們的演奏不同的球隊的關鍵識別(這裏有幾行,從格式文件複製)的:

playerID yearID league teamID G AB R H 2B 3B HR RBI SB CS 
aardsda01 2012 AL NYA 1         
aardsda01 2010 AL SEA 53 0 0 0 0 0 0 0 0 0 
aardsda01 2009 AL SEA 73 0 0 0 0 0 0 0 0 0 
aardsda01 2008 AL BOS 47 1 0 0 0 0 0 0 0 0 
aardsda01 2007 AL CHA 25 0 0 0 0 0 0 0 0 0 
abadfe01 2012 NL HOU 37 7 0 1 0 0 0 0 0 0 
abadfe01 2011 NL HOU 28 0 0 0 0 0 0 0 0 0 
abadfe01 2010 NL HOU 22 1 0 0 0 0 0 0 0 0 
abercre01 2008 NL HOU 34 55 10 17 5 0 2 5 5 2 
abercre01 2007 NL FLO 35 76 16 15 3 0 2 5 7 1 
abreubo01 2012 AL LAA 8 24 1 5 3 0 0 5 0 0 
abreubo01 2012 NL LAN 92 195 28 48 8 1 3 19 6 2 

因此,舉例來說,底部兩行,鮑比阿布雷烏效力的2012賽季兩支不同的球隊。

我如何將這兩行中的數字合併爲2012年賽季的相同playerId來計算他的2012年擊球平均數?

+0

你的問題不是很好問。你有閱讀文件的基本代碼,但你需要展示你解決特定問題的嘗試。沒有它,看起來你沒有嘗試,你希望我們爲你寫「硬」代碼。相反,嘗試,再試一次,再做一次,然後最後問一個關於那個具體問題的詳細問題。請參閱「[mcve]」和http://meta.stackoverflow.com/q/261592/128421 –

+0

我傾向於將其作爲一個副本關閉:您正在尋找有效地執行此操作 - http://stackoverflow.com/questions/18841698/group-hash-by-values-in-ruby – coreyward

+0

您需要了解陣列和散列及其用法之間的區別。它們是基本的組成部分,濫用或混淆它們會使相當簡單的問題變成噩夢。另外,CSV代表「逗號分隔值」。您的文件將是TSV(製表符分隔值)。 CSV可以對它們進行處理,只需稍微調整即可開始解析,但術語對於正確使用而言非常重要,尤其是在進入數據處理和數據庫時。 –

回答

1

在遍歷CSV數據時,您需要保留一個數據結構,該數據結構保存有關每個playerID的數據。使用哈希將是完美的。 ruby-doc.org manual page

require 'CSV' 

# Hashes are built into ruby. Using a hash literal 
# is more idomatic than h = Hash.new() */ 
h = {} 

CSV.foreach("Batting-07-12-resaved.csv",{:headers=>:first_row}) do |row| 
    if row[7].to_i != 0 && row[5].to_i != 0 && row[1].to_i == 2009 
     playerData = h[row[0]] 
     if (!playerData) 
      playerData = [row[0], row[7].to_f, row[5].to_f] 
     else 
      playerData = [row[0], row[7].to_f+playerData[1], row[5].to_f+playerData[2]] 
     end 

     h[row[0]]=playerData 
    end 
end 

h.each {|key, value| 
    puts "#{value[0]} is #{value[1]/value[2]}" 
} 
+0

我不知道'row [5]!= 0'是否會評估爲false。它可能需要'row [5] .to_i!= 0'。 – moveson

+2

而不是'Hash.new()'使用'{}'。當你必須指定默認值或使用塊形式時,第一種形式非常棒,否則'{}'是慣用的。 –

+0

感謝您的批評。我用更習慣的哈希構造更新了我的示例代碼(但留下評論以說明它不是魔術)。 'row [5]!= 0'轉換可能實際上是由於類型強制轉換而產生的,但它確實很難看,所以我添加了一個'.to_i'。 –

相關問題