2017-01-30 4 views
1

これは基本的にRuby経由で巨大なCSVファイルの情報を検索しようとしています。 )、私はUnixタイムスタンプを適切なTimeオブジェクトに変換し、それらをソートして#selectでフィルタリングしました。私は、この特定の時間範囲(start_date、end_dateで表される)を指定してpurchase_amtに関する情報を検索しようとしています。純粋なルビー:#selectでcsvの日付をフィルタリングしましたが、その日付範囲に基づいて別の列を取得したい

現在、巨大なcsvでフィルタリングされた時間の配列しかありませんが、どのようにしてcsvでpurchase_amtを取得するために自分のコードを使用できますか?

Unix_time purchase_amt 
1352948920 12.40 

require 'csv' 
require 'date' 

start_date = DateTime.rfc3339('2014-06-22T00:00:00Z').to_time.to_i 
end_date = DateTime.rfc3339('2014-07-22T00:00:00Z').to_time.to_i 

csv = CSV.parse('sample_data.csv', headers: true, encoding: 'ISO-8859-1') 

csv.each do |row| 
    if (row['created_at'] >= start_date && row['created_at'] <= end_date) 
     final_arry<< row 
    end 
end 

puts csv 
+0

私は前方にまっすぐであるCSV [「purchase_amt」]でpurchase_amtにアクセスしたいと思っていますが、Imは、私は、その後の対処方法を疑問に思いますこの大規模な配列と私は前に行ったフィルタリング作業を適用する... – cristodagama

+0

1つの解決策は、csvの最初の反復で列の値(Unix_time)を変更することができる...すべての列は、 start_dateまたはend_dateのどちらに該当するかを確認して、['purchase_amt']行を取得することができます。 – Abhinay

+0

あなたは明確にすることができますか?多分私に例を教えてください? – cristodagama

答えて

3

のために働くなら、私はあなたが巨大なCSVを使用している場合、あなたはを使用する必要があります知ってみましょう。 ファイル全体をメモリにロードせずに行を順番に解析します。

Range#cover?も役立ちます:objが始まり、範囲の端部との間にある場合

はtrueを返します。

可能であれば、新しい配列を返さずにブロック内のすべての計算も行う必要があります。ので、ここで、あなたがが巨大な配列をしたいです思える行く:

require 'csv' 

amounts = [] 

start_date = Time.new(2012, 1, 22) 
end_date = Time.new(2014, 7, 22) 

search_range = (start_date.to_i..end_date.to_i) 

CSV.foreach('data.csv', headers: true, col_sep: "\s", skip_blanks: true) do |row| 
    next unless search_range.cover?(row['Unix_time'].to_i) 
    amounts << row['purchase_amt'].to_f 
end 

p amounts 
+0

これは私が@ EricDuminilを望むものに非常に近いですが、合計amtを合計するのではなく、検索範囲内で販売された各prices_amtsのリストがほしいだけです。それは理にかなっていますか? – cristodagama

+0

Lnの代わりに、基本的には、私は個々のamtを配列で取り出すことができると考えていました – cristodagama

1

私が間違っていない場合は、start_date..end_dateの範囲に該当するレコードを抽出します。ここに述べたように

require 'date' 

DateTime.rfc3339('2015-05-27T07:39:59Z') 
#=> #<DateTime: 2015-05-27T07:39:59+00:00 ((2457170j,27599s,0n),+0s,2299161j)> 

DateTime.rfc3339('2015-05-27T07:39:59Z').to_time 
#=> 2015-05-27 09:39:59 +0200 

DateTime.rfc3339('2015-05-27T07:39:59Z').to_time.to_i 
#=> 1432712399 

https://stackoverflow.com/a/30480999/2545197

は今、あなたのようなCSVファイルを介して実行することができるはずです は今より良い解決策はただのようなUnixタイムスタンプにあなたのSTART_DATEとEND_DATEを変換することです

csv = CSV.parse('sample_data.csv', :headers => true, :encoding => 'ISO-8859-1') 
csv.each do |row| 
    # apply your conditions here 
    # something like... 
    if row['date'] >=start_date && row['date']<=end_date 
    # append it to some array 
    # ary << row 
    end 
end 

これはあなた

+0

それでは何も出力していません...あなたのことを示すために上のコードを更新してください。 – cristodagama

+0

私は出力がありません....更新を参照してください。 – cristodagama

+0

購入amtを究極的にベースにしたい日付選択の条件 – cristodagama

関連する問題