ホームページ バックエンド開発 Golang Go を使用した大規模な CSV 処理

Go を使用した大規模な CSV 処理

Nov 27, 2024 am 12:54 AM

アイデアは次のとおりです:

大規模なダミー CSV (100 万行) に顧客データのサンプルが含まれているとすると、以下の目標で処理を実行します。

  • CSV からデータを抽出します
  • データ/行数を計算します
  • 各都市の顧客数をグループ化
  • 顧客数の多い順に都市を並べ替えます
  • 処理時間を計算する
顧客のサンプル CSV はここからダウンロードできます https://github.com/datablist/sample-csv-files

データのロードと抽出

どうやら Go には CSV 処理用の標準ライブラリがあるようです。問題を解決するためにサードパーティに依存する必要がなくなりました。これは素晴らしいことです。したがって、解決策は非常に簡単です:


  // open the file to a reader interface
  c, err := os.Open("../data/customers-1000000.csv")
  if err != nil {
    log.Fatal(err)
  }
  defer c.Close()

  // load file reader into csv reader
  // Need to set FieldsPerRecord to -1 to skip fields checking
  r := csv.NewReader(c)
  r.FieldsPerRecord = -1
  r.ReuseRecord = true
  records, err := r.ReadAll()
  if err != nil {
    log.Fatal(err)
  }
ログイン後にコピー
ログイン後にコピー
    指定されたパスからファイルを開きます
  1. 開いているファイルを CSV リーダーにロードします
  2. 抽出されたすべての CSV レコード/行の値を、後で処理できるようにレコード スライスに保持します
各形式でフィールドまたは列の数が異なる可能性があるため、行のフィールドチェックをスキップしたいため、FieldsPerRecord を -1 に設定します

この状態では、CSV からすべてのデータをロードして抽出することができており、次の処理状態に進む準備ができています。また、関数 len(records) を使用すると、CSV 内の行数を知ることができます。

総顧客数を各都市にグループ化

これで、レコードを反復処理して、次のような都市名と総顧客数を含むマップを作成できるようになりました。


["Jakarta": 10, "Bandung": 200, ...]
ログイン後にコピー
ログイン後にコピー
CSV 行の都市データは 7 番目のインデックスにあり、コードは次のようになります


  // create hashmap to populate city with total customers based on the csv data rows
  // hashmap will looks like be ["city name": 100, ...]
  m := map[string]int{}
  for i, record := range records {
    // skip header row
    if i == 0 {
    continue
    }
    if _, found := m[record[6]]; found {
      m[record[6]]++
    } else {
      m[record[6]] = 1
    }
  }
ログイン後にコピー
ログイン後にコピー
都市マップが存在しない場合は、新しいマップを作成し、顧客の合計を 1 に設定します。それ以外の場合は、指定された都市の合計数を増やすだけです。

これで、都市のコレクションとその中に含まれる顧客の数を含むマップ m ができました。この時点で、都市ごとに何人の顧客をグループ化するかという問題はすでに解決しています。

最大合計顧客の並べ替え

標準ライブラリにマップを並べ替える関数があるかどうか探してみましたが、残念ながら見つかりませんでした。インデックス位置に基づいてデータの順序を並べ替えることができるため、スライスでのみソートが可能です。それでは、現在のマップからスライスを作成しましょう。


// convert to slice first for sorting purposes
dc := []CityDistribution{}
for k, v := range m {
  dc = append(dc, CityDistribution{City: k, CustomerCount: v})
}
ログイン後にコピー
それでは、CustomerCount を最大値から最小値までどのように並べ替えたのでしょうか?このための最も一般的なアルゴリズムは、バブルショートを使用することです。最速ではありませんが、十分な仕事はできます。

バブル ソートは、隣接する要素の順序が間違っている場合に繰り返し入れ替えることで機能する最も単純な並べ替えアルゴリズムです。このアルゴリズムは、平均および最悪の場合の時間計算量が非常に高いため、大規模なデータセットには適していません。

参考: https://www.geeksforgeeks.org/bubble-sort-algorithm/

スライスを使用して、データをループし、インデックスの次の値をチェックし、現在のデータが次のインデックスより小さい場合はそれを交換します。詳細なアルゴリズムは参考サイトで確認できます。

並べ替えプロセスは次のようになります

  // open the file to a reader interface
  c, err := os.Open("../data/customers-1000000.csv")
  if err != nil {
    log.Fatal(err)
  }
  defer c.Close()

  // load file reader into csv reader
  // Need to set FieldsPerRecord to -1 to skip fields checking
  r := csv.NewReader(c)
  r.FieldsPerRecord = -1
  r.ReuseRecord = true
  records, err := r.ReadAll()
  if err != nil {
    log.Fatal(err)
  }
ログイン後にコピー
ログイン後にコピー

ループの終わりまでに、最後のスライスからソートされたデータが得られます。

処理時間の計算

処理時間の計算は非常に簡単で、プログラムのメイン処理の実行前後のタイムスタンプを取得し、その差分を計算します。 Go では、アプローチは十分に単純である必要があります。

["Jakarta": 10, "Bandung": 200, ...]
ログイン後にコピー
ログイン後にコピー

結果

コマンドでプログラムを実行します

  // create hashmap to populate city with total customers based on the csv data rows
  // hashmap will looks like be ["city name": 100, ...]
  m := map[string]int{}
  for i, record := range records {
    // skip header row
    if i == 0 {
    continue
    }
    if _, found := m[record[6]]; found {
      m[record[6]]++
    } else {
      m[record[6]] = 1
    }
  }
ログイン後にコピー
ログイン後にコピー

出力されるのは、行数、ソートされたデータ、および処理時間です。以下はこのようなものです:

Large CSV Processing Using Go

期待通りの Go パフォーマンスで、100 万行の CSV を 1 秒以内に処理しました!

完成したコードはすべて私の Github リポジトリですでに公開されています:

https://github.com/didikz/csv-processing/tree/main/golang

学んだ教訓

  • Go での CSV 処理は標準ライブラリですでに利用可能であるため、サードパーティのライブラリを使用する必要はありません
  • データの処理は非常に簡単です。課題は、手動で行う必要があるため、データを並べ替える方法を見つけることでした

何が思い浮かびますか?

CSV を抽出したすべてのレコードをループしてマップし、ReadAll() ソースでチェックすると、指定されたファイル リーダーに基づいてスライスを作成するループも含まれているため、現在のソリューションをさらに最適化できるかもしれないと考えていました。これにより、100 万行で 100 万のデータに対して 2 つのループが生成される可能性があり、これは好ましくありません。

ファイル リーダーから直接データを読み取ることができれば、そこからマップを直接作成できるため、必要なループは 1 つだけであると考えました。ただし、レコードのスライスは他の場所で使用されますが、この場合は使用されません。

まだそれを理解する時間がありませんが、手動で行う場合のマイナス面も考えました:

  • おそらく解析プロセスのさらに多くのエラーを処理する必要があります
  • この回避策が価値があるかどうかを考えるのに、処理時間の短縮にどれだけの意味があるかわかりません

コーディングを楽しんでください!

以上がGo を使用した大規模な CSV 処理の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Golangの目的:効率的でスケーラブルなシステムの構築 Golangの目的:効率的でスケーラブルなシステムの構築 Apr 09, 2025 pm 05:17 PM

GO言語は、効率的でスケーラブルなシステムの構築においてうまく機能します。その利点には次のものがあります。1。高性能:マシンコードにコンパイルされ、速度速度が速い。 2。同時プログラミング:ゴルチンとチャネルを介してマルチタスクを簡素化します。 3。シンプルさ:簡潔な構文、学習コストとメンテナンスコストの削減。 4。クロスプラットフォーム:クロスプラットフォームのコンパイル、簡単な展開をサポートします。

Golang and C:Concurrency vs. Raw Speed Golang and C:Concurrency vs. Raw Speed Apr 21, 2025 am 12:16 AM

Golangは並行性がCよりも優れていますが、Cは生の速度ではGolangよりも優れています。 1)Golangは、GoroutineとChannelを通じて効率的な並行性を達成します。これは、多数の同時タスクの処理に適しています。 2)Cコンパイラの最適化と標準ライブラリを介して、極端な最適化を必要とするアプリケーションに適したハードウェアに近い高性能を提供します。

Golang vs. Python:重要な違​​いと類似点 Golang vs. Python:重要な違​​いと類似点 Apr 17, 2025 am 12:15 AM

GolangとPythonにはそれぞれ独自の利点があります。Golangは高性能と同時プログラミングに適していますが、PythonはデータサイエンスとWeb開発に適しています。 Golangは同時性モデルと効率的なパフォーマンスで知られていますが、Pythonは簡潔な構文とリッチライブラリエコシステムで知られています。

Golang vs. Python:パフォーマンスとスケーラビリティ Golang vs. Python:パフォーマンスとスケーラビリティ Apr 19, 2025 am 12:18 AM

Golangは、パフォーマンスとスケーラビリティの点でPythonよりも優れています。 1)Golangのコンピレーションタイプの特性と効率的な並行性モデルにより、高い並行性シナリオでうまく機能します。 2)Pythonは解釈された言語として、ゆっくりと実行されますが、Cythonなどのツールを介してパフォーマンスを最適化できます。

パフォーマンスレース:ゴラン対c パフォーマンスレース:ゴラン対c Apr 16, 2025 am 12:07 AM

GolangとCにはそれぞれパフォーマンス競争において独自の利点があります。1)Golangは、高い並行性と迅速な発展に適しており、2)Cはより高いパフォーマンスと微細な制御を提供します。選択は、プロジェクトの要件とチームテクノロジースタックに基づいている必要があります。

Golangの影響:速度、効率、シンプルさ Golangの影響:速度、効率、シンプルさ Apr 14, 2025 am 12:11 AM

speed、効率、およびシンプル性をspeedsped.1)speed:gocompilesquilesquicklyandrunseffictient、理想的なlargeprojects.2)効率:等系dribribraryreducesexexternaldedenciess、開発効果を高める3)シンプルさ:

CとGolang:パフォーマンスが重要な場合 CとGolang:パフォーマンスが重要な場合 Apr 13, 2025 am 12:11 AM

Cは、ハードウェアリソースと高性能の最適化が必要なシナリオにより適していますが、Golangは迅速な開発と高い並行性処理が必要なシナリオにより適しています。 1.Cの利点は、ハードウェア特性と高い最適化機能に近いものにあります。これは、ゲーム開発などの高性能ニーズに適しています。 2.Golangの利点は、その簡潔な構文と自然な並行性サポートにあり、これは高い並行性サービス開発に適しています。

GolangとC:パフォーマンスのトレードオフ GolangとC:パフォーマンスのトレードオフ Apr 17, 2025 am 12:18 AM

GolangとCのパフォーマンスの違いは、主にメモリ管理、コンピレーションの最適化、ランタイム効率に反映されています。 1)Golangのゴミ収集メカニズムは便利ですが、パフォーマンスに影響を与える可能性があります。

See all articles