Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
F# 阅读「;“尴尬”;使用FSharp CsvParser的CSV文件_F#_F# Data - Fatal编程技术网

F# 阅读「;“尴尬”;使用FSharp CsvParser的CSV文件

F# 阅读「;“尴尬”;使用FSharp CsvParser的CSV文件,f#,f#-data,F#,F# Data,我有一个大文件(200K-300K行文本)。 它几乎是一个CSV文件,但不完全是 列标题在第二行,有一行伪文本 在那之前 有一些行散布在实际数据行中。他们有 逗号,但大多数列为空。它们与我无关 我需要高效地读取此文件,并解析实际存在的行 有效,作为CSV数据 我的第一个想法是写一个干净的程序,删掉第一行和空白行,只留下我想要的页眉和细节。 CsvParser可以读取的CSV文件中 这很简单,只要从StreamReader中读取行,我就可以通过将每一行视为字符串来保留或忽略它 现在我有一个新的问题

我有一个大文件(200K-300K行文本)。 它几乎是一个CSV文件,但不完全是

  • 列标题在第二行,有一行伪文本
    在那之前

  • 有一些行散布在实际数据行中。他们有 逗号,但大多数列为空。它们与我无关

  • 我需要高效地读取此文件,并解析实际存在的行 有效,作为CSV数据

    我的第一个想法是写一个干净的程序,删掉第一行和空白行,只留下我想要的页眉和细节。 CsvParser可以读取的CSV文件中

    这很简单,只要从StreamReader中读取行,我就可以通过将每一行视为字符串来保留或忽略它

    现在我有一个新的问题

    有效数据中有一列我可以用来忽略更多的行

    如果我使用CsvParser读取清理过的文件,就很容易通过该列进行过滤

    但是,我真的不想浪费时间将不需要的行写入干净的文件

    我希望能够在清理文件时检查该列。但是,在这一点上,我正在使用表示整行的字符串。要找到我想要的特定专栏并不容易

    我不能在“,”上拆分,其他列的文本中可能有逗号。 我最终编写了Csv解析逻辑,这是我最初使用CsvParser的目的

    理想情况下,我希望读入现有的文件,清除基于字符串的行,然后使用CsvParser以某种方式解析生成的seq

    我看到CsvFile可以从流和读卡器加载,但我不确定这是否有多大帮助


    有什么建议吗?还是我问得太多了?我是否应该在加载清理过的文件时处理额外的过滤?

    通过直接使用
    CsvFile
    类,可以避免大部分解析工作

    有一些扩展示例详细说明了如何执行此操作

    在文件开头跳过行由
    skipRows
    参数处理。传递
    ignoreErrors
    参数也将忽略无法解析的行

    open FSharp.Data
    let csv = CsvFile.Load(file, skipRows=1, ignoreErrors=true)
    for row in csv.Rows do
        printfn "%s" row.GetColumn "Name"
    
    如果必须对行进行更复杂的筛选,一种不需要临时文件的简单方法是筛选
    File.ReadLines
    的结果并将其传递给
    CsvFile.Parse

    下面的示例跳过一个六行的前奏,逐行读取,直到它碰到一个空行,使用
    CsvFile
    解析数据,最后将结果行过滤到感兴趣的行

    let tableA =
        File.ReadLines(file)
        |> Seq.skip(6) 
        |> Seq.takeWhile(fun l -> String.length l > 0) 
        |> String.concat "\n"
    
    let csv = CsvFile.Parse(tableA)
    for row in csv.Rows.Filter(fun row -> row?Close.AsFloat() > row?Open.AsFloat()) do
        printfn "%s" row.GetColumn "Name"
    

    仅供参考,在没有任何更好的想法的情况下,我最初将写入一个临时文件,其中删除了格式错误的行。然后使用CsvParser过滤其他行并写入实际的干净文件。如果您向我们展示文件的外观,我们将更容易提供帮助。不是所有的200k行,但足以抓住问题的本质。从描述来看,我认为不到10行就可以完成。最好是看到一个样本,甚至连一个要点的链接都可以。我认为您最初使用tmp文件的解决方案是有意义的。您可以探索的另外两种方法是指定csv文件的模式并使用忽略错误选项;或者使用另一个.net csv解析器,如FileHelpers。