集計を始める前の10項目:行数・型・範囲・重複を見るデータ点検シート
AIを使いこなすClaudeで執筆し、GPTで自動校閲・修正しています。

集計の前に確認すべきことは、突き詰めると「1行が何を表すか」「行数は想定どおりか」「型は正しいか」「値の範囲は妥当か」「重複と欠損はどうなっているか」の5点です。この順で見ると、合計が合わない、平均が極端にずれるといった手戻りの原因をかなり早く見つけられます。 順番には理由があります。行数と1行の意味が曖昧なまま重複を探しても、何が重複なのか決められません。型が文字列のままだと、最小値・最大値の確認も当てになりません。そのため、上から順に埋める形の点検シートにしました。以下のシートは、コピーしてスプレッドシートやメモに貼って使えます。 なお、この記事の記入例の数字はすべて「説明用の例」で、実在のデータを集計した結果ではありません。コードも私が実行して確かめたものではなく、pandasの公式ドキュメントで確認した関数の使い方に沿って書いた雛形です。
10項目の点検シート
「確認すること」を見て、「記入欄」に結果を書きます。判定は、問題なしなら○、要対応なら△、集計に進めないなら×です。
- 1、項目:出所と1行の意味、確認すること:取得元、取得日、1行が何(1注文か、1明細か、1人か)を表すか、記入欄:
- 2、項目:行数・列数、確認すること:元システムの件数や前回データと照らし、想定との差はいくつか、記入欄:
- 3、項目:列名と単位、確認すること:列名の意味、金額の税込/税抜、数量の単位、不要な列、記入欄:
- 4、項目:型、確認すること:数値列・日付列が文字列になっていないか、記入欄:
- 5、項目:数値の範囲、確認すること:最小・最大・中央値に、ありえない値(負の数量、桁違い)がないか、記入欄:
- 6、項目:日付の範囲、確認すること:期間が依頼内容と合っているか、未来日や極端に古い日付がないか、記入欄:
- 7、項目:カテゴリの表記、確認すること:「東京」「東京都」「 東京」のような表記ゆれがないか、記入欄:
- 8、項目:重複、確認すること:全列が同じ行、キー列(注文番号など)が同じ行の件数、記入欄:
- 9、項目:欠損、確認すること:列ごとの欠損数と割合。空文字や「不明」「-」が欠損の代わりになっていないか、記入欄:
- 10、項目:突合、確認すること:総件数や合計金額が、元システムや既存の報告値と一致するか、記入欄:
項目1〜3は「データの外」の情報と照らす作業で、4〜9はデータ自身を調べる作業です。10は最後に全体を締めます。
項目ごとの見方と、つまずきやすい点
行数・列数と1行の意味(項目1〜3)
最初にやるのは、1行が何を表すかを一文で書くことです。「1行=1注文」と思っていたのに実際は「1行=1商品明細」なら、行数を数えるだけで注文数だと誤解します。行数が元システムの件数と違う場合は、その差を記入欄に書きます。差の理由がまだ分からなくても、差があるという事実を残すことが大切です。
型と値の範囲(項目4〜6)
pandasのDataFrame.info()は、行数にあたるインデックスの範囲、列ごとの非null数とデータ型を表示します。非null数を出すかどうかはデータの大きさで自動判定されるので、大きなデータで表示されないときはshow_counts=Trueを指定します。金額の列が数値型でなく文字列型と表示されたら、カンマや「円」が混じっていないかを疑ってください。
型を整えたら、DataFrame.describe()で数値列の件数、平均、標準偏差、最小、四分位、最大を見ます。文字列列はinclude='all'を付けると、件数、ユニーク数、最頻値、その出現回数が出ます。ここで重要なのは、平均ではなく最小値と最大値です。負の数量や桁違いの金額は、平均に混ざる前に最小・最大で目立ちます。なおdescribe()は計算時に欠損を除外するので、列の件数が行数より少なければ、それは欠損の手がかりになります。
日付は「期間が依頼と合うか」を見ます。最小日と最大日を書き出し、依頼された集計期間と並べて確認します。
重複と欠損(項目7〜9)
重複は2種類に分けて数えます。全列が同じ行と、キー列だけが同じ行です。pandasのDataFrame.duplicated()は、既定ですべての列を比べ、subsetで比べる列を指定できます。keepが既定の'first'だと最初の1行は重複扱いにならず、keep=Falseなら重複するすべての行に印が付きます。「どの行を消すか」を決める前に、keep=Falseで重複グループ全体を目で見るのが安全です。
欠損は、DataFrame.isna()がNone、NaN、NaTを欠損と見なす一方、空文字列''は欠損と見なさない点に注意が必要です。CSVから読んだ「空欄」の扱いは読み込み方で変わり得るため、isna()の件数が0でも安心しないでください。空文字や「不明」「-」の件数も別に数えます。
突合(項目10)
最後に、総件数と合計金額を、データ外の数字と照らします。ここが一致すれば、途中の変換で行が落ちていないことの強い根拠になります。一致しなければ、項目2に戻って差を追います。
記入例(説明用の例)
次は、架空の「月次注文データ」に対する記入例です。数字は説明のために作ったもので、実測ではありません。
- 1、項目:出所と1行の意味、記入例:受注管理画面から10/25にCSV出力。1行=1注文明細、判定:○
- 2、項目:行数・列数、記入例:画面の明細件数は1,200、CSVは1,248行。差48行、判定:△
- 3、項目:列名と単位、記入例:amountは税込。memo列は集計に不要、判定:○
- 4、項目:型、記入例:amountが文字列型。「1,200円」形式が混在、判定:△
- 5、項目:数値の範囲、記入例:quantityの最小が-3。返品行の可能性、判定:△
- 6、項目:日付の範囲、記入例:依頼は9月分だが、8/31の行が5件、判定:△
- 7、項目:カテゴリの表記、記入例:地域列に「東京」「東京都」の2表記、判定:△
- 8、項目:重複、記入例:全列一致が48行。項目2の差と同数、判定:△
- 9、項目:欠損、記入例:regionが12行空文字。isna()では0件、判定:△
- 10、項目:突合、記入例:重複除去後の行数は1,200、合計金額は画面値と一致するか要確認、判定:保留
この例では、項目2の差48行と項目8の重複48行が一致しています。こうして項目同士をつなげて読むと、原因の仮説が立ちます。ただし「重複を消せばよい」とは限りません。同じ明細が二重に出力されたのか、正当な同一内容の注文なのかは、元システムの担当者に確認して決めます。
確認用コードの雛形
dfにデータを読み込み済みという前提の雛形です。未実行のため、列名は自分のデータに合わせて直してください。
# df: 読み込み済みのDataFrame(列名は説明用)
key = ["order_id", "line_no"] # 1行を特定するキー列
print(df.shape) # 行数・列数(項目2)
df.info(show_counts=True) # 型と非null数(項目4)
print(df.describe()) # 数値の範囲(項目5)
print(df.describe(include="all")) # 文字列列の件数・ユニーク数・最頻値
print(df["order_date"].min(), df["order_date"].max()) # 項目6
# ※order_dateが文字列型だと、並びが日付順とは限らない
print(df["region"].value_counts(dropna=False)) # 項目7: 表記ゆれ
print(df.duplicated().sum()) # 全列一致(項目8)
dup = df[df.duplicated(subset=key, keep=False)] # キー一致の全行
print(len(dup))
print(dup.sort_values(key).head(20)) # 目視用
print(df.isna().sum()) # 項目9
print((df["region"] == "").sum()) # 空文字も別に数える結果を貼ったあとの判断は、次の表を目安にしてください。これは私の編集上の目安で、公式の基準ではありません。
- 行数が想定と違う、まずやること:差の件数を記録し、出力条件(期間・フィルタ)を確認、集計に進んでよいか:理由が分かるまで保留
- 数値が文字列型、まずやること:記号や単位を取り除く変換方針を決める、集計に進んでよいか:変換後に項目4・5をやり直してから
- 範囲外の値、まずやること:元データで確認。誤りか、返品などの正当な値かを分ける、集計に進んでよいか:扱いを決めてから
- 全列一致の重複、まずやること:keep=Falseで目視し、二重出力か確認、集計に進んでよいか:削除方針を記録してから
- 欠損・空文字、まずやること:列ごとの件数と、集計への影響を書く、集計に進んでよいか:影響が小さい列なら可
- 突合が不一致、まずやること:項目2に戻って差を追う、集計に進んでよいか:不可
AIに任せる範囲と、人が確認する範囲
AIには、点検結果の読み取りと、確認用コードの下書きを任せられます。一方、重複を削除してよいか、負の数量を除外するかといった業務上の判断は、データの意味を知る人が決めます。
AIに渡すのは、実データの全体ではなく、列名と型、info()やdescribe()の出力、数行のダミー行で足ります。顧客名や住所などは、説明用の値に置き換えてください。サービス側の学習利用の設定と、情報が外に出ないことは別の話なので、設定の有無にかかわらず、渡す情報は最小限にします。
依頼文の例です。【】の部分を置き換えて使います。
あなたはデータ点検の補助役です。次の情報から、集計前に確認すべき点を挙げてください。
【データの説明】1行=1注文明細。取得日【】。想定行数【】
【列と型】(df.info()の出力を貼る)
【統計】(df.describe(include="all")の出力を貼る)
【重複・欠損の件数】(件数のみを貼る)
条件:
- 原因を断定せず、「可能性」と「元データで確認する方法」を分けて書く
- 行を削除する提案は、確認が済むまで保留として書く
- 追加で必要な情報があれば、最後に質問として列挙するAIの回答は、推測を含む下書きとして扱います。「この重複は二重登録です」と書かれていても、その根拠が貼った情報に含まれているかを確認してください。
使い方のコツ
点検シートは、データを受け取るたびに1枚作り、集計結果と一緒に保存しておくと、数字の根拠を後から説明しやすくなります。毎回10項目すべてを深掘りする必要はありません。まず全項目に一行ずつ書き、△と×だけを追いかけます。慣れてきたら、コードの雛形を自分のデータの列名に直して、そのまま使い回してください。

