如何在GO中将.csv文件按列进行筛选

huangapple go评论82阅读模式
英文:

How to filter .csv file into columns on GO

问题

我正在尝试过滤一个.csv文件,只包括用户指定的两列。我的当前代码只能过滤.csv文件到一列(但当我写入一个.csv文件时,结果是一行而不是一列)。有没有办法在Go中过滤两列并将结果写入单列?

另外,有没有办法将数据写入列而不是行?

import (
	"encoding/csv"
	"fmt"
	"io"
	"log"
	"os"
)

func main() {
	file, err := os.Open("sample.csv")
	checkError(err)

	reader := csv.NewReader(file)
	_, err = reader.Read() //跳过标题
	checkError(err)
	results := make([]string, 0)

	for {
		row, err := reader.Read()
		if err == io.EOF {
			break
		}
		if err != nil {
			log.Fatal(err)
		}
		//fmt.Println(row[columnNum])
		results = append(results, row[columnNum])

	}
	fmt.Print(results)

	//文件创建
	f, err := os.Create("results.csv")
	checkError(err)
	defer f.Close()

	w := csv.NewWriter(f)
	err = w.Write(results)
	checkError(err)
	w.Flush()
}
英文:

I am trying to filter a .csv file to only include 2 columns that will be specified by the user. My current code can only filter the .csv file to one column (but when I write to a .csv file, the results are in a row instead of a column) . Any ideas on how to filter the two columns and write the results in a single column on Go? Seems

In addition, is there any way I can write the data as a column instead of a row?

import (
	"encoding/csv"
	"fmt"
	"io"
	"log"
	"os"
)
func main() {
        file, err := os.Open("sample.csv")
		checkError(err)

		reader := csv.NewReader(file)
		_, err = reader.Read() //Skips header
		checkError(err)
		results := make([]string, 0)

		for {
			row, err := reader.Read()
			if err == io.EOF {
				break
			}
			if err != nil {
				log.Fatal(err)
			}
			//fmt.Println(row[columnNum])
			results = append(results, row[columnNum])

		}
		fmt.Print(results)

		//File creation
		f, err := os.Create("results.csv")
		checkError(err)
		defer f.Close()

		w := csv.NewWriter(f)
		err = w.Write(results)
		checkError(err)
		w.Flush()
}

</details>


# 答案1
**得分**: 0

&gt; ...有没有办法将数据写成列而不是行?

您只是在写入单个列。您调用了一次`w.Write`,它会[将单个记录写入CSV](https://golang.org/pkg/encoding/csv/#Writer.Write)。如果您每读取一行就写入一次,您将得到多行。请注意,您多次调用了`Read`和一次调用了`Write`。

&gt; 有没有办法在Go中过滤两列并将结果写入单列?

要获取两列,您只需要同时访问两列 - 我现在看到每行只有一个访问(`row[columnNum]`),所以您只需要第二个访问。结合我之前的观点,我认为主要问题是您忽略了CSV是二维的,但您只存储了一个一维数组。

我不确定您所说的“写入单列”是什么意思 - 也许您想要将CSV的长度加倍,或者您想要以某种方式合并两列?

无论哪种情况,我建议重新构造您的代码,避免构建中间的`results`数组,而是在读取后直接写入。这样做更高效,并且更直接地将旧格式映射到新格式。

```go
	file, err := os.Open("sample.csv")
	checkError(err)

	reader := csv.NewReader(file)
	_, err = reader.Read() // 跳过标题
	checkError(err)

	// 立即创建文件和写入器
	f, err := os.Create("results.csv")
	checkError(err)
	defer f.Close()

	w := csv.NewWriter(f)

	for {
		row, err := reader.Read()
		if err == io.EOF {
			break
		}
		if err != nil {
			log.Fatal(err)
		}
		// 在这里 - 每行都写入新的CSV写入器
		err = w.Write([]string{row[columnNum]})

        // 将两列写入每行的示例
		// err = w.Write([]string{row[columnNum1], row[columnNum2]})

        // 合并两列的示例
		// err = w.Write([]string{fmt.Sprintf("%s - %s", row[columnNum1], row[columnNum2])})

		checkError(err)
	}

	w.Flush()
英文:

> ...is there any way I can write the data as a column instead of a row?

You're only writing a single column. You call w.Write once, which writes a single record to the CSV. If you write once per consumed row, you'll get multiple rows. Notice that you're calling read Read many times and Write once.

> Any ideas on how to filter the two columns and write the results in a single column on Go?

To get two columns, you just need to access both - I see one access to each row right now (row[columnNum]), so you'll just need a second. Combined with my previous point, I think the main problem is that you're missing that CSVs are two dimensional but you're only storing a single dimensional array.

I'm not sure what you mean by "write to a single column" - maybe you want to double the length of the CSV, or maybe you want to somehow merge two columns?

In either case, I'd suggest restructuring your code to avoid building up the intermediate results array, and instead write directly after reading. This will be more performant and more directly maps from the old format to the new one.

	file, err := os.Open(&quot;sample.csv&quot;)
	checkError(err)

	reader := csv.NewReader(file)
	_, err = reader.Read() // Skips header
	checkError(err)

	// Create the file and writer immediately
	f, err := os.Create(&quot;results.csv&quot;)
	checkError(err)
	defer f.Close()

	w := csv.NewWriter(f)

	for {
		row, err := reader.Read()
		if err == io.EOF {
			break
		}
		if err != nil {
			log.Fatal(err)
		}
		// here - each row is written to the new CSV writer
		err = w.Write([]string{row[columnNum]})

        // an example of writing two columns to each row
		// err = w.Write([]string{row[columnNum1], row[columnNum2]})

        // an example of merging two rows
		// err = w.Write([]string{fmt.Sprintf(&quot;%s - %s&quot;, row[columnNum1], row[columnNum2])})

		checkError(err)
	}

	w.Flush()

huangapple
  • 本文由 发表于 2021年5月25日 17:31:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/67685288.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定