ほとんどのCSVファイルは雑な状態で到着します。空のセルがnullの場所にあり、引用符が不一致で、スキーマが強制されていません。これをきれいなJSONに変換することは、フォーマットの変更ではなく、データのクリーニング問題です。
このガイドでは、変換を行うべきタイミング、変換中に起こる問題、およびエッジケースを正しく処理する方法をカバーしています — すなわち、簡単な CSVからJSONへの変換ツール またはカスタムスクリプトを使用する方法です。
CSVとJSON:誠実なトレードオフ
CSVはコンパクトで、世界中で読みやすく、スプレッドシートに簡単にインポートできます。平坦なテーブルデータ — データベースからのエクスポート、分析パイプライン、財務記録 — にはまだ適したフォーマットです。データが行と列に収まっている場合、ネストがなければ、CSVは十分です。
JSONが適しているのは次のケースです:
- データにネストや階層がある場合(複数の住所を持つユーザー)
- 明示的な型情報が必要な場合(数値42と文字列“42”)
- APIまたはJavaScriptアプリケーションにデータを渡す場合
- nullを明示的に表現したい場合、空のセルだけでは表現できません
このトレードオフは「どちらのフォーマットがより良いか」という話ではありません。データの構造がCSVが表現できない範囲を超えていないかという点にあります。
CSVが引き起こす問題
変換する前に、何が壊れているかを理解する必要があります。
nullの標準がない。 CSVの空セルはnull、ゼロ、空文字列、またはデータの欠落を意味する可能性があります。ファイルからその意味を判断することはできません。空の列は1つのシステムでは「不明」となり、別のシステムでは「0」となり得ます。 age 引用符の不一致。
コンマを含む値はダブルクォートで囲まなければなりません( )、しかしすべてのエクスポートツールがその規格を遵守しているわけではありません。未引用のコンマ、不一致な引用符、引用符を開始したが終了しないセルが見られます。"Portland, OR"エンコーディングの問題。
CSVファイルはしばしばUTF-8 BOM、Windows-1252文字、またはその組み合わせで到着します。スマートクォート、emダッシュ、アクセント文字などは、純粋なASCIIを期待するパーサーに障害をもたらします。 型情報がない。
CSVのすべての値は文字列として保存されます。数値42、論理値true、日付2024-01-01はすべてテキストとして保存されます。盲目的にJSONに変換すると、数値や論理値を期待した場所にテキストが含まれるようになります。 正確に変換する方法
メカニズムはシンプルです:CSVの各行がJSONオブジェクトに変換され、列ヘッダーがキーになります。問題は、そのマッピングの前後にあるすべての処理です。
型変換。
整数の列はJSONの数値に変換され、true/falseの値を持つ列は論理値に変換されます。しかし、ZIPコードのような整数に見える列(90210)は文字列として保持すべきです — 変換すると先頭のゼロが失われます。 nullの処理。
空のセルには決定が必要です: 、キーを完全にスキップ、またはデフォルト値を使用します。1つを選択し、すべての行で一貫性を保ちます。 null欠落するフィールド。
1行がヘッダーより少ない列を持つ場合、パーサーはそれを適切に処理する必要があります — すなわち、 を埋めるか、行をスキップするかです。 null 以下は、すべてのケースを処理するPythonのスニペットです:
エンコーディングはBOMが存在する場合にそれを削除します。
import csv
import json
def coerce_value(value):
if value == '':
return None
try:
return int(value)
except ValueError:
pass
try:
return float(value)
except ValueError:
pass
if value.lower() in ('true', 'false'):
return value.lower() == 'true'
return value
def csv_to_json(csv_path, json_path):
with open(csv_path, encoding='utf-8-sig') as f: # utf-8-sig strips BOM
reader = csv.DictReader(f)
rows = []
for row in reader:
rows.append({k: coerce_value(v) for k, v in row.items() if k})
with open(json_path, 'w', encoding='utf-8') as f:
json.dump(rows, f, indent=2, ensure_ascii=False)
csv_to_json('input.csv', 'output.json')
の utf-8-sig 数値変換を順に試みます:整数から始まり、浮動小数点数、論理値、文字列の順です。この coerce_value フィルターは、ヘッダー行の末尾のコンマによる幻の列を削除します。 if k フラットCSVからネストされたJSON
CSVは直接ネストを表現できませんが、2つの一般的な戦略があります。
ドットキー記法。
一部のCSVエクスポートは、ヘッダーを のように記述します。後処理ステップでドットを分割し、ネストされたオブジェクトを構築します: address.city と address.zipグループ化とネスト。
def unflatten(row):
result = {}
for key, value in row.items():
parts = key.split('.')
d = result
for part in parts[:-1]:
d = d.setdefault(part, {})
d[parts[-1]] = value
return result
複数の行が同じ親の子として表される場合(注文の下の注文行)、親IDでグループ化し、変換後にネストされた配列を構築します。どちらのアプローチも、一時的な変換ステップに属すべきではありません — あなたがこれを行う場合、あなたはフォーマット変更のためのスクリプトを書いているのです。 使用すべきツール
フォーマット変更だけが必要な、きれいで適切なCSVの場合:オンライン
に貼り付け、変換、完了。設定や依存関係なし。 CSVからJSONへの変換ツール既知の問題があるCSV(エンコーディング、引用符の不一致、型変換、nullなど)の場合、スクリプトを書きます。上記のPythonスニペットはほとんどの実際のケースを処理します。pandasも選択肢ですが(
)、その独自の型変換決定が、あなたが望むものと一致しない可能性があります。pd.read_csv() + df.to_json()ターミナルでのワンライナーの場合、
ミラー )は最も速い方法です: (mlrミラーは、引用符、エンコーディング、および欠落するフィールドを、デフォルトで適切に処理します。問題のあるCSVからきれいなJSONへ変換するためのコードを書かず、最も速い方法です。
mlr --icsv --ojson cat input.csv > output.json
CSVのエッジケースとその処理方法
CSVの問題
| JSONが得る結果 | どのように処理するか | 空のセル |
|---|---|---|
| または欠落するキー | null 事前に決定し、すべての行で一貫性を保つ | 数値に見える文字列(ZIPコード) |
| 整数に変換すると先頭のゼロが失われる | 文字列として保持し、制御できる列のみに変換する | ヘッダーの末尾のコンマ |
| 空のキー | すべての行に "" を適用する | オブジェクト構築時に if k フィルターを適用する |
| ファイルの開始部にUTF-8 BOM | パーサーのエラーまたは の最初のキーに | を開く encoding='utf-8-sig' |
| セル内の引用符内に改行 | シンプルな行ごとのパーサーを破壊する | 実際のCSVパーサーを使用し、 split(',') |
"true"/"false" 論理値列 | "true" 文字列、ではなく true 論理値 | 小文字に変換した後、明示的な変換 |
フォーマット変更は簡単だが、データはそうではない。
CSVからJSONへの変換ツールは構造的な部分を数秒で処理できます。時間がかかるのは、ファイルに実際に含まれているnull、エンコーディングの問題、数値に見えるが実際には数値ではない列を理解することです。型変換やnull処理を明示的に書くことで、ツールが推測するのを信頼せず、下流のバグを回避できます。
恵 スコアボードが到着しました!
スコアボード ゲームを追跡する楽しい方法です。すべてのデータはブラウザに保存されます。さらに多くの機能がまもなく登場します!
