経緯
ソフトウェア分析の研究の再現を行なっていた際,ChatGPTに分析手順を説明してもらっていました.すると,下記のステップで紹介されました.
- ステップ1: 収集したプロジェクトのデータをCSVに保存する(←わかる)
- ステップ2: フィルターを適用させて残ったプロジェクトをjsonlに保存する(←んん??)
ここで,私はjsonlの存在を初めて知りました.
jsonのタイプミスかと思いましたが,違いました.
結論
jsonlはjsonの亜種で,json linesの略です.つまり,jsonを一列に並べたものです.
まずはjsonについて
jsonはこのように書きます.
[
{"repo": "react", "stars": 210000},
{"repo": "vue", "stars": 203000}
]
jsonlの書き方
{"repo": "react", "stars": 210000}
{"repo": "vue", "stars": 203000}
-
1行=1レコード(1オブジェクト)
-
各行が独立していて、カンマも配列の括弧も不要
-
各行がJSON形式として完結しているため、ストリーミング処理や部分読み込みが容易
jsonlの詳細と利点
部分読み込みができる
100GB級の巨大ファイルでも,各行が独立したJSON構造を持つため,ファイル全体をメモリに展開せずに1行ずつストリーム処理できます.Pythonなら以下のように扱えます.
import json
with open("data.jsonl") as f:
for line in f:
record = json.loads(line)
# 各レコードを逐次処理
→ データ全体を一度に読み込む必要がなく,メモリ消費はほぼ一定.
これは .json や .csv にはない強みです.
追記が簡単
普通のJSON配列では、最後に ] を閉じる必要があるため追記が面倒ですが,
JSONLは1行=1オブジェクトなので,以下のように簡単に追加できます.
with open("data.jsonl", "a") as f:
f.write(json.dumps({"repo": "vue", "stars": 200000}) + "\n")
→ JSON配列の整形や末尾修正を気にせず,「ログ感覚」で追加可能.
CIやGitHub APIのように逐次的に取得するデータとの相性が抜群です.
並列処理が可能
各行が完全に独立したJSONなので,ファイルを分割して並列処理できます.
たとえば:
split -l 100000 data.jsonl part_
で100,000行ずつ分割して,複数のCPUスレッドで分析できます.
MapReduceやSparkでもネイティブ対応しており,大規模マイニングに向いています.
→ MSR(Mining Software Repositories)系研究では,
Gitリポジトリ・コミットログ・依存関係差分をJSONLで保存し,
クラスタ上で分散解析するのが一般的です.
Git差分がわかりやすい
JSONLは行単位で意味を持つため,Gitやdiffコマンドで変更点がすぐ分かります.
例えば次のような差分:
- {"repo": "react", "stars": 200000}
+ {"repo": "react", "stars": 210000}
→ JSON配列形式だと1行が非常に長く,差分比較が困難.
JSONLなら「どのレコードが更新されたか」が明確です.
再現性を求める研究(論文のデータ共有など)に適しています.
pandasで簡単に読み込める
Pythonの pandas はJSONLを標準対応しており,
以下の1行でデータ解析用DataFrameに変換できます.
import pandas as pd
df = pd.read_json("data.jsonl", lines=True)
→ 各JSONオブジェクトが1行ずつ自動的に1レコード(行)として扱われます.
列構造が自動的に揃うため,統計分析や可視化がすぐ可能です.
例:依存関係更新頻度のヒストグラム、CIビルド失敗率の時系列など.