【问题标题】:Edit csv file in Scala在 Scala 中编辑 csv 文件
【发布时间】:2016-03-08 04:19:56
【问题描述】:

我想编辑 csv(超过 500MB)文件。 如果我有类似的数据

ID, NUMBER
A, 1
B, 3
C, 4
D, 5

我想添加一些额外的列,例如

ID, NUMBER, DIFF
A, 1, 0
B, 3, 2
C, 4, 1
D, 5, 1

此数据也可以是 ScSla 数据类型。

(in)Orgin Csv 文件 -> (out)(新建 csv 文件,文件数据(RDD 类型?))

第一季度。哪种方式是处理数据的最佳方式?

  1. 从原始 csv 文件创建一个新的 csv 文件,然后重新打开新的 csv 文件以 scala 数据。
  2. 先制作新的 scala 数据,并将其制作为 csv 文件。

第二季度。我需要为此使用“数据框”吗?我应该使用哪个库或 API?

【问题讨论】:

    标签: scala csv apache-spark


    【解决方案1】:

    一个相当简单的方法是使用kantan.csv

    import kantan.csv.ops._
    import kantan.csv.generic.codecs._
    import java.io.File
    
    case class Output(id: String, number: Int, diff: Int) 
    case class Input(id: String, number: Int)
    
    val data = new File("input.csv").asUnsafeCsvReader[Input](',', true)
                                    .map(i => Output(i.id, i.number, 1))
    
    new File("output.csv").writeCsv[Output](data.toIterator, ',', List("ID", "NUMBER", "DIFF"))
    

    无论数据大小如何,此代码都可以正常工作,因为我们绝不会将整个数据集(或者实际上不止一行)加载到内存中。

    请注意,在我的示例代码中,数据来自和去往File 实例,但它可以来自任何可以转换为Reader 实例的东西——一个URI、一个字符串...

    【讨论】:

    • 哦,我刚刚了解您的 DIFF 列是如何工作的。我的示例只是在其中粘贴了一个随机值,您需要对其进行一些修改以与前一个元素进行区分,但您可以通过相对简单的折叠来做到这一点。
    【解决方案2】:

    RDD 与 DataFrame:两者都是不错的选择。建议使用 DataFrames,它允许在幕后进行一些额外的优化,但对于足够简单的任务,性能可能相似。使用 DataFrames 的另一个优点是能够使用 SQL - 如果您对 SQL 感到满意,您可以加载文件,将其注册为临时表并查询它以执行任何转换。 DataFrames 的一个更相关的优势是能够使用databricks' spark-csv 库轻松读取和写入 CSV 文件。

    假设您现在将使用 DataFrames (DF):

    Flow:听起来你应该这样做

    1. 将原始文件加载到 DF,调用它input
    2. 将其转换为新的DF,称为withDiff
    3. 此时,缓存结果是有意义的,让我们调用缓存的DF result
    4. 现在您可以将result 保存到新的 CSV 文件中
    5. 再次使用result 处理您需要的任何其他内容

    【讨论】:

    • 谢谢它真的帮了我:)
    • 根据您以后要对数据执行的操作,DF 或 RDD 都可能不是一个很好的匹配项。您的“差异”列需要对文件进行线性运行,因此您无法从 Spark 的并行特性中获得任何收益。
    猜你喜欢
    • 1970-01-01
    • 2016-04-20
    • 1970-01-01
    • 1970-01-01
    • 2012-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-28
    相关资源
    最近更新 更多