2

我对使用 Accelerate 库很感兴趣,我想对存储在 CSV 文件中的数据执行一些操作。我已经阅读了这篇关于 Accelerate 的精彩介绍,但我不确定如何有效地将 CSV 读入 Accelerate。我考虑过这一点,我唯一能想到的就是将整个 CSV 文件解析成一个长列表,然后将整个列表输入到 Accelerate。

我的数据集将非常大,将 1 gb+ 的文件读入内存并复制到其他地方似乎效率不高。我注意到 Hackage 上有一个CSV Enumerator包,但我不确定如何将它与 Accelerate 的生成功能一起使用。另一个限制是,在使用 Accelerate 生成数组之前,似乎必须知道数组的维度或至少元素的数量。

以前有没有人处理过这种问题?

谢谢!

4

2 回答 2

1

我没有尝试将 CSV 文件读入 repa,但我建议使用木薯(http://hackage.haskell.org/package/cassava)。Iirc 我有一个 1.5G 的文件,我用它来创建我的统计数据。使用木薯,我的程序运行在非常小的内存中。这是一个扩展的用法示例:

http://idontgetoutmuch.wordpress.com/2013/10/23/parking-in-westminster-an-analysis-in-haskell/

在 repa 的情况下,如果您将行增量添加到数组中(这听起来像是您想要做的),那么人们会希望空间使用量也会增量增长。这当然值得一试。并且可能还联系repa人员。请报告您的结果:-)

于 2014-02-11T08:55:27.687 回答
1

我不确定这是否 100% 适用于accelerateor 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,也许这是您结合此方法的金票。

于 2014-02-10T05:08:49.037 回答