我有一个90GB的CSV文件,我需要从中提取一些列,然后将字符串更改为整数并将其存储在新的CSV中。我编写了代码并在大约100,000行的小样本CSV文件上对其进行了测试。它工作正常,所以我继续将原始CSV提供给程序。我知道这需要一夜之间完成,我早上发现程序没有完成,处理过的文件大小只有1GB左右,这真的很小,因为我预计到时候它至少要10 GB它完成了,允许整数占用的空间少于字符串,而且我只从原始CSV中提取50多列中的10个。
我修改了代码以分别进行提取和处理。我发现,如果没有处理,提取将在10-11小时内完成,从而产生尺寸为38GB的CSV。然后我对提取的CSV进行了处理,运行18小时后仍未完成,生成的CSV文件大小仅为1.5GB。
我的处理代码是:
require 'rubygems'
require 'mechanize'
require 'csv'
require 'time'
CSV.open('FormattedColumns.csv', "wb") do |csv|
csv << ["_time", "article_category_id", "articleID", "date_wday", "datetime", "lat", "lon", "platform", "push", "udid"]
CSV.foreach('ExtractedColumns.csv', :headers=>true) do |row|
time=Time.parse(row[0]).to_i
article_category_id=row[1].to_i
articleID=row[2].to_i
if row[3]=='sunday'
weekday=7
elsif row[3]=='saturday'
weekday=6
elsif row[3]=='friday'
weekday=5
elsif row[3]=='thursday'
weekday=4
elsif row[3]=='wednesday'
weekday=3
elsif row[3]=='tuesday'
weekday=2
elsif row[3]=='monday'
weekday=1
end
datetime = row[4].to_i
lat = row[5].to_f
lon = row[6].to_f
if row[7]=='Android'
platform=2
elsif row[7]=='iPhone'
platform=1
end
if row[8]=='Y'
push=1
elsif row[8]=='N'
push=0
end
unless udids.include?(row[9])
udids << row[9]
end
udid = udids.index(row[9]) + 1
array = [time, article_category_id, articleID, weekday, datetime, lat, lon, platform, push, udid]
csv<<array
end
end
这可能是什么原因?
据我所知,它是一个简单的程序,并且,对于100,000行的较小样本程序,当我分别尝试提取和处理时,它们都在大约1-2分钟内完成。
答案 0 :(得分:0)
您可能希望查看smarter_csv
gem,它可以处理CSV数据的块(多行)并将它们交给异步工作者,例如:一个Sidekiq工人。
为了编写输出,每个工作程序将每个批处理的输出片段组合成单独的文件并在以后连接它们可能会更快。