我有兴趣使用Accelerate库,我想对存储在CSV文件中的数据执行一些操作。我已经阅读了this excellent introduction to Accelerate,但我不确定如何有效地将CSV读入加速。我已经考虑过了,我唯一能想到的就是将整个CSV文件解析成一个长列表,然后将整个列表提供给Accelerate。
我的数据集非常大,将1 gb +文件读入内存只是为了复制到其他地方似乎并不高效。我注意到Hackage上有一个CSV Enumerator包,但我不确定如何将它与Accelerate的generate函数一起使用。另一个限制是,在使用Accelerate生成数组之前,似乎必须知道Array的维度或至少数量的元素。
之前有没有人处理过这类问题?
谢谢!
答案 0 :(得分:1)
我不确定这是否100%适用于accelerate
或repa
,但这是我过去为Vector处理此问题的一种方法:
-- | A hopefully-efficient sink that incrementally grows a vector from the input stream
sinkVector :: (PrimMonad m, GV.Vector v a) => Int -> ConduitM a o m (Int, v a)
sinkVector by = do
v <- lift $ GMV.new by
go 0 v
where
-- i is the index of the next element to be written by go
-- also exactly the number of elements in v so far
go i v = do
res <- await
case res of
Nothing -> do
v' <- lift $ GV.freeze $ GMV.slice 0 i v
return $! (i, v')
Just x -> do
v' <- case GMV.length v == i of
True -> lift $ GMV.grow v by
False -> return v
lift $ GMV.write v' i x
go (i+1) v'
它基本上分配by
个空槽并继续填充它们。一旦它到达天花板,它再次增长底层矢量。我没有基准测试任何东西,但它似乎在实践中表现良好。我很想知道这里是否会有更有效的答案。
希望这在某种程度上有所帮助。我确实在fromVector
中看到了一个repa
函数,也许这就是你与这种方法相结合的金票。
答案 1 :(得分:1)
我还没有尝试将CSV文件读入修复,但我建议使用木薯(http://hackage.haskell.org/package/cassava)。 Iirc我有一个1.5G文件,我用它来创建我的统计数据。使用木薯,我的程序运行的内存非常少。这是一个扩展的使用示例:
http://idontgetoutmuch.wordpress.com/2013/10/23/parking-in-westminster-an-analysis-in-haskell/
在修复的情况下,如果你逐行地向行添加行(听起来你想做),那么人们希望空间使用也会逐渐增长。这当然值得一个实验。也可能还联系了修理人员。请报告您的结果: - )