Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to skip the first row when reading a csv file?

Tags:

go

I have an awkward csv file and I need to skip the first row to read it.

I'm doing this easily with python/pandas

df = pd.read_csv(filename, skiprows=1)

but I don't know how to do it in Go.

package main

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

type mwericsson struct {
    id     string
    name   string
    region string
}

func main() {

    rows := readSample()

    fmt.Println(rows)
    //appendSum(rows)
    //writeChanges(rows)
}

func readSample() [][]string {
    f, err := os.Open("D:/in/20190629/PM_IG30014_15_201906290015_01.csv")
    if err != nil {
        log.Fatal(err)
    }
    rows, err := csv.NewReader(f).ReadAll()
    f.Close()
    if err != nil {
        log.Fatal(err)
    }
    return rows
}

Error:

2019/07/01 12:38:40 record on line 2: wrong number of fields

PM_IG30014_15_201906290015_01.csv:

PTN Ethernet-Port RMON Performance,PORT_BW_UTILIZATION,2019-06-29 20:00:00,33366     
DeviceID,DeviceName,ResourceName,CollectionTime,GranularityPeriod,PORT_RX_BW_UTILIZATION,PORT_TX_BW_UTILIZATION,RXGOODFULLFRAMESPEED,TXGOODFULLFRAMESPEED,PORT_RX_BW_UTILIZATION_MAX,PORT_TX_BW_UTILIZATION_MAX
3174659,H1095,H1095-11-ISM6-1(to ZJBSC-V1),2019-06-29 20:00:00,15,22.08,4.59,,,30.13,6.98
3174659,H1095,H1095-14-ISM6-1(to T6147-V),2019-06-29 20:00:00,15,2.11,10.92,,,4.43,22.45
like image 224
Morteza Hasanabadi Avatar asked Jul 01 '19 08:07

Morteza Hasanabadi


3 Answers

skip the first row when reading a csv file


For example,

package main

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

func readSample(rs io.ReadSeeker) ([][]string, error) {
    // Skip first row (line)
    row1, err := bufio.NewReader(rs).ReadSlice('\n')
    if err != nil {
        return nil, err
    }
    _, err = rs.Seek(int64(len(row1)), io.SeekStart)
    if err != nil {
        return nil, err
    }

    // Read remaining rows
    r := csv.NewReader(rs)
    rows, err := r.ReadAll()
    if err != nil {
        return nil, err
    }
    return rows, nil
}

func main() {
    f, err := os.Open("sample.csv")
    if err != nil {
        panic(err)
    }
    defer f.Close()
    rows, err := readSample(f)
    if err != nil {
        panic(err)
    }
    fmt.Println(rows)
}

Output:

$ cat sample.csv
one,two,three,four
1,2,3
4,5,6
$ go run sample.go
[[1 2 3] [4 5 6]]
$ 

$ cat sample.csv
PTN Ethernet-Port RMON Performance,PORT_BW_UTILIZATION,2019-06-29 20:00:00,33366     
DeviceID,DeviceName,ResourceName,CollectionTime,GranularityPeriod,PORT_RX_BW_UTILIZATION,PORT_TX_BW_UTILIZATION,RXGOODFULLFRAMESPEED,TXGOODFULLFRAMESPEED,PORT_RX_BW_UTILIZATION_MAX,PORT_TX_BW_UTILIZATION_MAX
3174659,H1095,H1095-11-ISM6-1(to ZJBSC-V1),2019-06-29 20:00:00,15,22.08,4.59,,,30.13,6.98
3174659,H1095,H1095-14-ISM6-1(to T6147-V),2019-06-29 20:00:00,15,2.11,10.92,,,4.43,22.45
$ go run sample.go
[[DeviceID DeviceName ResourceName CollectionTime GranularityPeriod PORT_RX_BW_UTILIZATION PORT_TX_BW_UTILIZATION RXGOODFULLFRAMESPEED TXGOODFULLFRAMESPEED PORT_RX_BW_UTILIZATION_MAX PORT_TX_BW_UTILIZATION_MAX] [3174659 H1095 H1095-11-ISM6-1(to ZJBSC-V1) 2019-06-29 20:00:00 15 22.08 4.59   30.13 6.98] [3174659 H1095 H1095-14-ISM6-1(to T6147-V) 2019-06-29 20:00:00 15 2.11 10.92   4.43 22.45]]
$
like image 97
peterSO Avatar answered Oct 16 '22 05:10

peterSO


Simply call Reader.Read() to read a line, then proceed to read the rest with Reader.ReadAll().

See this example:

src := "one,two,three\n1,2,3\n4,5,6"

r := csv.NewReader(strings.NewReader(src))
if _, err := r.Read(); err != nil {
    panic(err)
}

records, err := r.ReadAll()
if err != nil {
    panic(err)
}
fmt.Println(records)

Output (try it on the Go Playground):

[[1 2 3] [4 5 6]]
like image 40
icza Avatar answered Oct 16 '22 05:10

icza


while it was informative to learn about io.ReadSeeker, I think a simpler way to skip the first line/row (often times the header) of a csv is to use the slice functionality as follows:

func readCsv(filename string) [][]string {
    f, err := os.Open(filename)
    if err != nil {
        log.Fatal(err)
    }
    defer f.Close()
    records := [][]string{}
    r := csv.NewReader(f)
    for {
        record, err := r.Read()
        if err == io.EOF {
            break
        }
        if err != nil {
            log.Fatal(err)
        }
        records = append(records, record)
    }
    return records[1:] // skip the header
}
like image 31
Abhas Sinha Avatar answered Oct 16 '22 05:10

Abhas Sinha