当前位置: 首页 > 面试题库 >

在Go中高效读写CSV

袁泰平
2023-03-14
问题内容

下面的Go代码读取10,000条记录的CSV(时间戳times和浮点数values),对数据进行一些操作,然后将原始值以及的附加列写入到另一个CSV中score。但是,它的运行速度非常慢(例如,数小时,但大部分时间是calculateStuff()),我很好奇我可以处理的CSV读取/写入是否效率低下。

package main

import (
  "encoding/csv"
  "log"
  "os"
  "strconv"
)

func ReadCSV(filepath string) ([][]string, error) {
  csvfile, err := os.Open(filepath)

  if err != nil {
    return nil, err
  }
  defer csvfile.Close()

  reader := csv.NewReader(csvfile)
  fields, err := reader.ReadAll()

  return fields, nil
}

func main() {
  // load data csv
  records, err := ReadCSV("./path/to/datafile.csv")
  if err != nil {
    log.Fatal(err)
  }

  // write results to a new csv
  outfile, err := os.Create("./where/to/write/resultsfile.csv"))
  if err != nil {
    log.Fatal("Unable to open output")
  }
  defer outfile.Close()
  writer := csv.NewWriter(outfile)

  for i, record := range records {
    time := record[0]
    value := record[1]

    // skip header row
    if i == 0 {
      writer.Write([]string{time, value, "score"})
      continue
    }

    // get float values
    floatValue, err := strconv.ParseFloat(value, 64)
    if err != nil {
      log.Fatal("Record: %v, Error: %v", floatValue, err)
    }

    // calculate scores; THIS EXTERNAL METHOD CANNOT BE CHANGED
    score := calculateStuff(floatValue)

    valueString := strconv.FormatFloat(floatValue, 'f', 8, 64)
    scoreString := strconv.FormatFloat(prob, 'f', 8, 64)
    //fmt.Printf("Result: %v\n", []string{time, valueString, scoreString})

    writer.Write([]string{time, valueString, scoreString})
  }

  writer.Flush()
}

我正在寻求帮助,以使此CSV读/写模板代码尽快。对于此问题的范围,我们不必担心该calculateStuff方法。


问题答案:

您先将文件加载到内存中,然后再对其进行处理,这对于大文件而言可能会很慢。

您需要循环并一次调用.Read和处理一行。

func processCSV(rc io.Reader) (ch chan []string) {
    ch = make(chan []string, 10)
    go func() {
        r := csv.NewReader(rc)
        if _, err := r.Read(); err != nil { //read header
            log.Fatal(err)
        }
        defer close(ch)
        for {
            rec, err := r.Read()
            if err != nil {
                if err == io.EOF {
                    break
                }
                log.Fatal(err)

            }
            ch <- rec
        }
    }()
    return
}

playground

//请注意,它大致基于DaveC的评论。



 类似资料:
  • 问题内容: 我正在使用文件上传器,并且需要请求有效负载中的详细信息以进行裁剪。 我没有10位代表来发布POST请求的图片,但是它有 所以从avatar_data我所需要的,,,和。我知道我必须封送JSON,但是我不确定如何达到这一点? 问题答案: 实现接口。

  • 大家好,已经有人问过类似的问题,但我想我们有点不同的问题: 我们使用Cassandra 2.2.6一个节点安装(并将升级到最新的)。现在我们有可怕的查询时间,有时会写超时。 为了进行比较,有一个不同的表包含大约10万条记录,其构造与上述非常相似 区别在于第一个包含大量地图和UDT。在dev center中进行简单测试选择*from。。。限制999;(省略任何Lucene索引等)最后一个显示183m

  • 问题内容: 我正在python 2.7中读取800 GB的xml文件,并使用etree迭代解析器对其进行解析。 目前,我只使用没有缓冲参数。我是应该采用这种方法还是应该使用缓冲参数,还是应该使用io.BufferedReader或io.open或io.TextIOBase之类的方法,对此感到有些困惑。 朝正确方向的观点将不胜感激。 问题答案: 默认情况下,标准函数已经返回一个缓冲文件(如果在您的平

  • 本文向大家介绍如何写高效的CSS?相关面试题,主要包含被问及如何写高效的CSS?时的应答技巧和注意事项,需要的朋友参考一下 css大全,看下这篇文章吧,里面基本啥都有

  • 问题内容: 如何在go程序中读取xz文件?当我尝试使用阅读它们时,出现错误。 问题答案: 您有3个选择。 尝试另一个库,也许是使用cgo的库。我在这里看到两个。 直接使用cgo /创建自己的lib。 使用xz可执行文件。 选项三比听起来容易。这是我会用的: 此处可运行的代码:http : //play.golang.org/p/SrgZiKdv9a

  • 问题内容: 编辑:这是一组更完整的代码,确切显示了下面每个答案所发生的事情。 目的是仅根据类别成员资格在表中查询一些ID。然后,我总结了这些成员在所有类别中的活动。 上面的方法比以下方法慢得多: 运行第一个查询以获取子集 运行第二个查询求和每个ID 运行内部连接第三个结果集的第三个查询。 如果我理解正确,那么确保完全通过我的所有代码而不是交叉加载可能会更有效率。 在昨天发表问题后,一位成员建议我从