【Python】pandasとmatplotlibで在庫データのABC分析と構成比を可視化してみた

【Python】pandasとmatplotlibで在庫データのABC分析と構成比を可視化してみた

公開: 更新:
CodeCampが提供するDX人材育成が可能なプログラミングやITが学べる公開講座

在庫管理の定番手法「ABC分析」を、Pythonのpandasで実装して4種類のグラフに可視化してみました。numpyの合成データで動くので外部ファイルは不要、コードをコピーすればそのまま追体験できます。sort_valuescumsumpd.cutの3ステップによる分析と、パレート図など4枚の描き分けのコツを初心者向けに解説します。

【Python】pandasとmatplotlibで在庫データのABC分析と構成比を可視化してみた|概要動画
動画の内容をテキストで確認する

オープニング。pandasを使った実践内容を約34秒で紹介します。概要紹介。

この動画では、Pythonのpandasで在庫データをABC分析し、構成比をグラフで可視化します。具体的にやること。具体的には、pandasで出荷金額の構成比と累積構成比を計算してA・B・Cランクに分類し、matplotlibでパレート図など4種類のグラフを描きます。

実装環境・必須アプリ。実装環境と必須アプリは、Windows 11 Pro / Python 3.13.3 / pandasです。実際のキャプチャ動画。

実際の画面で操作を確認します。検証の結果、実際に4枚の図を生成できました。エンディング。

研修ならCodeCampで検索。

Pythonとpandasで在庫のABC分析を作る方針

在庫管理の現場では「どの商品を重点管理するか」を決めるのにABC分析がよく使われます。今回は60品目の在庫データをPythonで用意し、pandasでランク分けからグラフ化までを一気通貫でやってみました。

データはnumpyで合成し、シードを42に固定しているのがポイントです。外部のCSVやAPIに依存しないため、コードを実行すれば誰でも記事と同じ結果を再現できます。

出荷数は対数正規分布で生成し、「一部の商品が売上の大半を占める」という実際の在庫らしい偏りを再現しました。分析本体はsort_valuescumsumpd.cutの3ステップだけなので、pandasの基本操作の練習にもちょうどよい題材です。

可視化はmatplotlibで、パレート図・積み上げ横棒・上位10品目の横棒・ヒートマップと役割の違う4枚を描き分けます。A=赤・B=黄・C=青の配色を全図で統一して、どの図を見てもランクが一目で分かるようにしました。

このセクションの用語

ABC分析
出荷金額などの重要度で在庫をA・B・Cの3ランクに分類する手法。少数の重要品目に管理の力を集中させるために使われる。
パレート図
値の大きい順に並べた棒グラフに、累積構成比の折れ線を重ねた図。「上位2割が全体の8割を占める」といった偏りを一目で確認できる。
対数正規分布
少数の大きな値と多数の小さな値に偏る分布。売上や出荷数など、実世界のデータによく現れる形。
SKU
在庫管理の最小単位(Stock Keeping Unit)。この記事ではSKU-001のような商品コードとして使っている。
ABC分析パイプラインの全体像。pandasの基本操作だけで完結する numpyで60品目の合成データを生成出荷金額の降順にsort_values構成比とcumsumで累積構成比を計算pd.cutでA・B・Cランクを判定matplotlibで4種類のグラフを保存
ABC分析パイプラインの全体像。pandasの基本操作だけで完結する
さらに詳しく学べるPython研修の詳細はこちら

Pythonでpandasのコードを生成したプロンプトと作り方

この記事のコードはClaude Codeに書かせたもので、別のAIであるCodexにレビューさせています。以下は、その際に使った指示の内容です。

在庫のABC分析は手順が決まった定型処理なので、プロンプトでは手法名だけに頼らず、「金額の降順に並べる→構成比→累積構成比→70%・90%で区切る」という計算の流れを番号付きで書き切ることを最優先にしました。手順を明示したほうがLLMの出力が安定し、生成されたコードのレビューもしやすくなります。

もう1つの柱は再現性です。合成データの分布(対数正規)とシード値42を固定したことで読者の手元でも記事とほぼ同じグラフが再現でき、パレート図・積み上げ横棒・ヒートマップという4枚の指定も「どの観点を見るための図か」まで含めて意味を持ちます。

生成プロンプトで工夫したポイント

  • 乱数のシードは42で固定し、出荷数は対数正規分布にする:分布とシードを固定すると実行のたびに結果が変わらず、記事と同じグラフを読者の手元でも再現できます。対数正規分布は「一部の商品に偏る」在庫の実態に近く、ABC分析の題材として意味のあるデータになるのもポイントです。
  • 累積構成比が70%までをAランク、90%までをBランク、残りをCランクとしてpd.cutで分類する:ABC分析は閾値の解釈が人によって揺れるため、基準の数値と使う関数を名指しして出力のぶれを抑えました。
  • 棒グラフ=金額、折れ線=累積構成比。70%・90%の基準線も引く:「パレート図」と一言で頼むと構成がまちまちになるので、棒・折れ線・基準線という部品単位で完成形を確定させる狙いです。
  • ランク別の品目数構成比と金額構成比を並べた積み上げ横棒グラフ:品目数ではわずかなAランクが金額では大半を占める、というABC分析の結論そのものが1枚で伝わります。

同じコードを作れる生成プロンプト(コピペ用・全文)

以下のプロンプトは、そのままコピペして同じものが作れるように整えた全文です。

Pythonで在庫データのABC分析を行い、構成比をグラフで可視化するスクリプトを書いてください。 ## 使うライブラリ - pandas、numpy、matplotlib ## データ - 外部ファイルは使わず、コード内で60品目分の在庫データを合成する - 列は商品コード・カテゴリ(飲料/食品/日用品/文具/衛生用品)・単価・年間出荷数 - 乱数のシードは42で固定し、出荷数は対数正規分布にする(一部の商品に出荷が偏る、実際の在庫らしい形にするため) ## 分析の手順 1.年間出荷金額(単価×年間出荷数)を計算する 2.金額の降順に並べ替え、構成比と累積構成比を求める 3.累積構成比が70%までをAランク、90%までをBランク、残りをCランクとしてpd.cutで分類する ## 可視化(4枚をfigsフォルダにPNG保存する) 1.パレート図(棒グラフ=金額、折れ線=累積構成比。70%・90%の基準線も引く) 2.ランク別の品目数構成比と金額構成比を並べた積み上げ横棒グラフ 3.金額構成比の上位10品目の横棒グラフ 4.カテゴリ×ランクの品目数ヒートマップ ## 出力 - 最後にランク別の品目数と金額構成比のサマリーを表示する - グラフのタイトル・軸ラベル・凡例は日本語にする - ランクの色はA=赤系・B=黄系・C=青系で全部のグラフに統一する
さらに詳しく学べるPython研修の詳細はこちら

Python・pandasの環境構築(Windows 11/PowerShellで検証)

この記事のセットアップ手順と掲載コードは、Windows 11 Pro、PowerShell 5.1、Python 3.13.3で動作確認しています。仮想環境を有効化せず、その中のPythonを直接指定するため、以下のコマンドはPowerShellとコマンドプロンプト(cmd)の両方で使えます。

python -m venv .venv
.\.venv\Scripts\python.exe -m pip install pandas numpy matplotlib

macOS・Linuxでは仮想環境内のPythonパスが異なります。今回の動作確認環境とは異なるため、以下は環境差分を補う参考手順です。

python3 -m venv .venv
./.venv/bin/python -m pip install pandas numpy matplotlib
  • 手元の環境でグラフの日本語ラベルが文字化け(豆腐表示)する場合は、コード冒頭でmatplotlib.rcParams["font.family"]に"Meiryo"などの日本語フォント名を指定してください。
  • pd.cutで作るランク列はcategorical型のため、集計時はgroupby("ランク", observed=True)としておくと将来のpandasでの挙動変更警告を避けられます。

Python研修一覧はこちら

目的に合うPython研修を一覧形式から探したい方は、ぜひご利用ください。

Python研修を比較する

Java研修一覧はこちら

目的に合うJava研修を一覧形式から探したい方は、ぜひご利用ください。

Java研修を比較する

PHP研修一覧はこちら

目的に合うPHP研修を一覧形式から探したい方は、ぜひご利用ください。

PHP研修を比較する

新入社員研修

目的に合う新入社員研修を一覧形式から探したい方は、ぜひご利用ください。

新入社員研修を比較する

全ての研修からも探したい方はこちら

pd.cutとcumsumで書くPython実装

コード全体はanalyzeという1つの関数にまとまっていて、データ生成→ABC分析→4枚の描画→保存という流れで上から順に読めます。ここでは「ここだけ押さえれば分かる」という要所を抜き出して解説します。

肝になるのはABC分析の3行です。金額の降順に並べてから構成比を足し上げ、累積が70%までをA、90%までをB、残りをCと機械的に判定します。

このセクションの用語

DataFrame
行と列を持つ表形式データを扱うpandasの中心的な入れ物。Excelの表をプログラムで操作するイメージに近い。
累積和
先頭からその行までの値を順に足し合わせた合計。cumsumで計算でき、累積構成比の算出に使う。
カテゴリ型
「A・B・C」のように決まった選択肢だけを取るpandasのデータ型。pd.cutの結果はこの型で返る。
バックエンド
matplotlibが図を描くときに使う描画エンジン。Aggは画面表示を持たず、PNGなどのファイル出力に特化している。
"""在庫データのABC分析と構成比の可視化。"""

import os

import numpy as np
import pandas as pd
import matplotlib

matplotlib.use("Agg")
import matplotlib.pyplot as plt
from matplotlib.patches import Patch


def analyze(out_dir: str) -> dict:
    """在庫データを合成し、ABC分析と構成比のグラフをout_dirへ保存して要約を返す。"""

    # 在庫データの生成(シードを固定し、出荷数は対数正規分布で偏らせる)
    rng = np.random.default_rng(42)
    n_items = 60
    categories = ["飲料", "食品", "日用品", "文具", "衛生用品"]
    df = pd.DataFrame(
        {
            "商品コード": [f"SKU-{i:03d}" for i in range(1, n_items + 1)],
            "カテゴリ": rng.choice(categories, size=n_items),
            "単価": rng.integers(80, 1500, size=n_items),
            "年間出荷数": rng.lognormal(mean=5.0, sigma=1.0, size=n_items).astype(int) + 1,
        }
    )
    df["年間出荷金額"] = df["単価"] * df["年間出荷数"]

    # ABC分析(金額の降順に並べ、構成比・累積構成比からランクを判定)
    df = df.sort_values("年間出荷金額", ascending=False).reset_index(drop=True)
    df["構成比"] = df["年間出荷金額"] / df["年間出荷金額"].sum()
    df["累積構成比"] = df["構成比"].cumsum()
    df["ランク"] = pd.cut(df["累積構成比"], bins=[0, 0.7, 0.9, 1.0], labels=["A", "B", "C"])
    rank_colors = {"A": "#e8684a", "B": "#f6bd16", "C": "#5b8ff9"}
    bar_colors = [rank_colors[r] for r in df["ランク"]]

    # 図1: パレート図(棒=出荷金額、折れ線=累積構成比、70%と90%に基準線)
    fig, ax1 = plt.subplots(figsize=(10, 5))
    ax1.bar(df.index + 1, df["年間出荷金額"] / 10000, color=bar_colors, width=0.8)
    ax1.set_xlabel("品目(出荷金額の降順)")
    ax1.set_ylabel("年間出荷金額(万円)")
    ax2 = ax1.twinx()
    ax2.plot(df.index + 1, df["累積構成比"] * 100, color="#333333", linewidth=1.5)
    ax2.axhline(70, color="#888888", linestyle="--", linewidth=1)
    ax2.axhline(90, color="#888888", linestyle=":", linewidth=1)
    ax2.set_ylabel("累積構成比(%)")
    ax2.set_ylim(0, 105)
    handles = [Patch(color=rank_colors[r], label=f"{r}ランク") for r in "ABC"]
    ax1.legend(handles=handles, loc="center right")
    ax1.set_title("パレート図: 出荷金額と累積構成比によるABC分析")
    fig.tight_layout()
    fig.savefig(os.path.join(out_dir, "pareto_chart.png"), dpi=150)
    plt.close(fig)

    # 図2: ランク別の品目数と出荷金額の構成比(積み上げ横棒で偏りを比較)
    rank_summary = df.groupby("ランク", observed=True).agg(
        品目数=("商品コード", "count"), 金額構成比=("構成比", "sum")
    )
    rank_summary["品目数構成比"] = rank_summary["品目数"] / n_items
    fig, ax = plt.subplots(figsize=(9, 3.5))
    labels = ["品目数", "出荷金額"]
    left = np.zeros(2)
    for rank in ["A", "B", "C"]:
        values = 100 * np.array(
            [rank_summary.loc[rank, "品目数構成比"], rank_summary.loc[rank, "金額構成比"]]
        )
        ax.barh(labels, values, left=left, color=rank_colors[rank], label=f"{rank}ランク")
        for i, v in enumerate(values):
            ax.text(left[i] + v / 2, i, f"{v:.0f}%", ha="center", va="center", color="white")
        left += values
    ax.set_xlim(0, 100)
    ax.set_xlabel("構成比(%)")
    ax.set_title("ランク別の品目数と出荷金額の構成比")
    ax.legend(loc="lower right")
    fig.tight_layout()
    fig.savefig(os.path.join(out_dir, "rank_share.png"), dpi=150)
    plt.close(fig)

    # 図3: 金額構成比の上位10品目(横棒で主力商品を確認)
    top10 = df.head(10).iloc[::-1]
    fig, ax = plt.subplots(figsize=(8, 5))
    ax.barh(
        top10["商品コード"],
        top10["構成比"] * 100,
        color=[rank_colors[r] for r in top10["ランク"]],
    )
    ax.set_xlabel("金額構成比(%)")
    ax.set_title("出荷金額の構成比 上位10品目")
    fig.tight_layout()
    fig.savefig(os.path.join(out_dir, "top10_share.png"), dpi=150)
    plt.close(fig)

    # 図4: カテゴリ×ランクの品目数ヒートマップ(重点管理すべきカテゴリを探す)
    cross = pd.crosstab(df["カテゴリ"], df["ランク"])
    fig, ax = plt.subplots(figsize=(6.5, 4.5))
    im = ax.imshow(cross.values, cmap="Blues")
    ax.set_xticks(range(len(cross.columns)))
    ax.set_xticklabels([f"{c}ランク" for c in cross.columns])
    ax.set_yticks(range(len(cross.index)))
    ax.set_yticklabels(cross.index)
    for i in range(cross.shape[0]):
        for j in range(cross.shape[1]):
            color = "white" if cross.values[i, j] > cross.values.max() / 2 else "#333333"
            ax.text(j, i, cross.values[i, j], ha="center", va="center", color=color)
    fig.colorbar(im, ax=ax, label="品目数")
    ax.set_title("カテゴリ×ランクの品目数")
    fig.tight_layout()
    fig.savefig(os.path.join(out_dir, "category_rank_heatmap.png"), dpi=150)
    plt.close(fig)

    # 要約の作成(ランク別の品目数と金額構成比を返す)
    return {
        "品目数": int(n_items),
        "総出荷金額": int(df["年間出荷金額"].sum()),
        "ランク別品目数": {str(k): int(v) for k, v in rank_summary["品目数"].items()},
        "ランク別金額構成比": {
            str(k): round(float(v), 3) for k, v in rank_summary["金額構成比"].items()
        },
        "保存した図": [
            "pareto_chart.png",
            "rank_share.png",
            "top10_share.png",
            "category_rank_heatmap.png",
        ],
    }

コード全文は上の折り畳みに入れてあるので、全部を上から読む必要はありません。ここでは特に重要な部分だけを抜き出して、何をしているのか順番に見ていきます。

default_rngで偏りのある在庫データを合成する

rng = np.random.default_rng(42)
n_items = 60
categories = ["飲料", "食品", "日用品", "文具", "衛生用品"]

default_rng(42)で乱数生成器をシード42に固定するのがこの行の役割です。乱数を使っていても毎回同じデータが出てくるので、記事と同じ結果を手元でも再現できます。品目数60とカテゴリ5種の定義もここに置きました。

lognormalで出荷数を現実の売れ方に近づける

"年間出荷数": rng.lognormal(mean=5.0, sigma=1.0, size=n_items).astype(int) + 1,

出荷数を一様乱数ではなくlognormal(対数正規分布)で生成しているのがこだわりです。これで「爆売れする少数の商品と、細々と動く多数の商品」という現実的な偏りが生まれ、ABC分析のしがいがあるデータになります。末尾の+1は出荷数0の品目を作らないための保険でした。

sort_valuesとcumsumで累積構成比を出す

df = df.sort_values("年間出荷金額", ascending=False).reset_index(drop=True)
df["構成比"] = df["年間出荷金額"] / df["年間出荷金額"].sum()
df["累積構成比"] = df["構成比"].cumsum()

ABC分析の心臓部です。金額の大きい順に並べ替えないと累積構成比が意味を持たないため、sort_values(ascending=False)が必ず先に来ます。cumsumは先頭から順に足し合わせる累積和で、各行には「その行までの構成比の合計」が入る仕組みでした。

pd.cutで累積構成比をA・B・Cに切り分ける

df["ランク"] = pd.cut(df["累積構成比"], bins=[0, 0.7, 0.9, 1.0], labels=["A", "B", "C"])
rank_colors = {"A": "#e8684a", "B": "#f6bd16", "C": "#5b8ff9"}

pd.cutは連続値を区間で区切ってラベルを貼る関数で、累積構成比0〜70%をA、70〜90%をB、90〜100%をCに割り当てました。しきい値を変えたいときはbinsの数値を書き換えるだけで済みます。配色の辞書をここで1回だけ定義し、4枚すべての図で使い回すのがコツです。

twinxで棒と折れ線の2軸パレート図を組む

ax2 = ax1.twinx()
ax2.plot(df.index + 1, df["累積構成比"] * 100, color="#333333", linewidth=1.5)
ax2.axhline(70, color="#888888", linestyle="--", linewidth=1)
ax2.axhline(90, color="#888888", linestyle=":", linewidth=1)

パレート図は棒(金額)と折れ線(累積%)で単位が違うため、twinxで右側に2本目のy軸を作るのが定石です。axhlineで70%と90%の位置に水平の基準線を引いておくと、折れ線と交わる場所からランクの境目を読み取れるようになります。

groupbyのobserved=Trueでランク別に集計する

rank_summary = df.groupby("ランク", observed=True).agg(
    品目数=("商品コード", "count"), 金額構成比=("構成比", "sum")
)

ランクごとの品目数と金額構成比をまとめて集計する部分です。pd.cutが返すランク列はカテゴリ型なので、observed=Trueを付けて実際に存在する値だけを集計対象にしました。aggに「新しい列名=(元の列, 集計方法)」を渡す書き方は、結果の列名を自分で決められて便利です。

参考:

©pandas公式ドキュメント

Use cut when you need to segment and sort data values into bins. This function is also useful for going from a continuous variable to a categorical variable.

さらに詳しく学べるPython研修の詳細はこちら

PythonのpandasコードをCodexにレビューさせた結果

プロンプトから作ったコードは、一見動いていても抜けや改善点が潜んでいることがあります。エラーにならない=正しい、ではないのが怖いところです。

そこで、コードを書いたClaude Codeとは別のAIであるCodexに同じコードをレビューさせ、指摘をそのまま載せます。書き手と読み手を別のAIに分けると、自分では気づきにくい問題を洗い出せます。

指摘 深刻度 改善案
out_dirが存在しない場合にos.path.joinで保存先を作成せず、fig.savefigがFileNotFoundErrorになる。 保存処理の前にos.makedirs(out_dir, exist_ok=True)を呼び出して出力ディレクトリを確実に作成する。
analyzeが入力データを受け取らず乱数で在庫データを生成するため、実際の在庫データのABC分析には利用できない。 データフレームを引数で受け取り、商品コード・単価・年間出荷数などの必要列を検証する構成に変更する。
rank_summaryにA、B、Cのいずれかが存在しない場合、rank_summary.loc[rank]がKeyErrorになってグラフ作成に失敗する。 reindex(['A','B','C'], fill_value=0)で全ランクを補完してから各値を参照する。
累積構成比が浮動小数点誤差で1.0をわずかに超えるとpd.cutがNaNを生成し、rank_colors[r]でKeyErrorになる可能性がある。 累積構成比をclip(upper=1.0)で補正してからランク判定を行い、未分類値も明示的に検査する。
固定された基準値と乱数データだけで結果を作るため、分析結果の再現性はあるが実運用データの欠損値や異常値を検出できない。 入力列の欠損・0以下の単価や出荷数・重複商品コードを検証し、問題があれば分かりやすい例外を出す。

Python基礎・実践(Django)

企業・法人向けのPython研修では、基礎から応用まで体系的に学べます。

Python研修の詳細

DX社員研修

企業・法人向けのDX研修では、実務に繋がるリスキリングでITレベルを向上させます。

DX研修の詳細

Javaエンジニア育成研修

企業・法人向けのJavaエンジニア育成研修では、Javaの基礎から応用まで確実に習得できます。

Java研修の詳細

新卒・新入社員向け研修

企業・法人に新入社員・新卒社員に向けたプログラミング研修を提供しています。

新入社員研修の詳細

コードキャンプのIT研修を全て見る

Pythonで4枚のグラフを生成した実行結果

スクリプトを実行すると、エラーなく4枚のPNGが出力フォルダに保存されました。パレート図、ランク別構成比の積み上げ横棒、上位10品目の横棒、カテゴリ×ランクのヒートマップという役割の違う4枚です。

パレート図では棒がランクごとに赤・黄・青へ塗り分けられ、累積構成比の折れ線が70%と90%の基準線と交わる位置からランクの境目を読み取れます。積み上げ横棒は品目数と出荷金額の構成比を上下に並べ、両者の偏りの差を見比べるための作りです。

集計結果の主な数値は次のとおりです。60品目の合成データで、総出荷金額は7,517,383円になりました。

ヒートマップはカテゴリ×ランクのクロス集計で、どのカテゴリにAランク品目が集まっているかを色の濃淡で確認できます。上位10品目の横棒と合わせて見ると、「全体の傾向」と「個別の重点商品」の両方を1セットで押さえられる構成です。

このセクションの用語

ヒートマップ
表の各マスを値の大小に応じた色の濃淡で塗った図。数字の羅列よりも傾向を直感的に掴める。
クロス集計
2つの軸(ここではカテゴリとランク)を掛け合わせて件数などを集計する方法。偏りの所在を面で把握できる。
項目 実測値
品目数 60
総出荷金額 7,517,383円
生成された図1: category_rank_heatmap
生成された図1: category_rank_heatmap
生成された図2: pareto_chart
生成された図2: pareto_chart
生成された図3: rank_share
生成された図3: rank_share
生成された図4: top10_share
生成された図4: top10_share
項目 実測値
品目数 60
総出荷金額 7517383
ランク別品目数 {"A": 22, "B": 16, "C": 22}
ランク別金額構成比 {"A": 0.693, "B": 0.205, "C": 0.101}
保存した図 pareto_chart.png、rank_share.png、top10_share.png、category_rank_heatmap.png
さらに詳しく学べるPython研修の詳細はこちら

pandasのABC分析でよくあるPythonエラーと対処

ここでは、この構成のコードを書くときに初心者が遭遇しやすいエラーを一般論として整理します。エラーメッセージは長く見えますが、最後の1行に原因の要約が出るので、まずそこを読むのが近道です。

このセクションの用語

トレースバック
エラーに至るまでの呼び出し履歴の表示。下の行ほど発生箇所に近く、最終行にエラー名と要約が出る。
エラー例 原因 対処
ModuleNotFoundError: No module named 'pandas' ライブラリ未インストール、または別のPython環境で実行している pip install pandas numpy matplotlibを実行する。python -m pip install ...なら環境のずれも防げる
KeyError: '年間出荷金額' 列名の打ち間違いや全角・半角の不一致 print(df.columns)で実際の列名を確認し、コード側を合わせる
ValueError: bins must increase monotonically pd.cutbinsが小さい順に並んでいない bins=[0, 0.7, 0.9, 1.0]のように昇順に書き直す
FileNotFoundError(savefig実行時) 保存先フォルダが存在しない os.makedirs(out_dir, exist_ok=True)で事前にフォルダを作っておく
グラフの日本語が□(豆腐)になる matplotlibに日本語フォントが設定されていない japanize-matplotlibを導入するか、rcParamsで日本語フォント名を指定する
さらに詳しく学べるPython研修の詳細はこちら

累積構成比の計算でつまずきやすいポイント

文法エラーにはならないのに結果が静かにおかしくなる、という落とし穴がこのテーマにはいくつかあります。コードを書く前に、次のポイントだけ頭に入れておくと安全です。

このセクションの用語

NaN
「値が存在しない」ことを表す欠損値。計算やランク判定から外れてしまうため、意図せず発生していないかの確認が必要。
POINT

sort_valuesのあとのreset_index(drop=True)を忘れると、行番号が並べ替え前のまま残ってしまいます。df.index + 1をx軸に使うパレート図では順位が飛び飛びに描かれる原因になるため、この2つは必ずセットで書いてください。

今回の累積構成比は必ず0より大きいのでbins=[0, 0.7, 0.9, 1.0]のままで問題ありません。ただし0ちょうどの値を区切るデータでは、include_lowest=Trueを付けないと先頭の値がNaNになる点に注意が必要です。

groupbyobserved=Trueは、カテゴリ型の列を集計するときの重要オプションです。付けない場合の既定動作はバージョンによって異なり、該当データが1件もないランクの行が集計に紛れ込むことがあります。

matplotlib.use("Agg")import matplotlib.pyplotより前に書かないと効きません。順番を逆にすると設定が無視され、画面のない環境では描画時にエラーが出ることもあるので、冒頭2行の順序はそのまま守るのが安全です。

累積構成比は「降順に並べ替えてから」計算して初めて意味を持ちます。並べ替えを飛ばしてcumsumだけ実行しても数値自体は出てしまうため、結果を眺めただけでは間違いに気付きにくい点が厄介です。

さらに詳しく学べるPython研修の詳細はこちら

ECや営業でも使えるABC分析の応用場面

ABC分析は在庫管理の手法として有名ですが、「少数の要素が全体の大半を占める」データなら何にでも応用が利きます。今回のコードは列名を差し替えるだけで、そのまま別のデータに転用できる作りです。

いずれの場面でもsort_valuescumsumpd.cutという骨格は共通で、変わるのは集計対象の列だけです。まずは手元のデータをpd.read_csvpd.read_excelで読み込み、今回の合成データ部分と差し替えてみてください。

このセクションの用語

パレートの法則
「全体の8割の成果は2割の要素が生む」という経験則。ABC分析はこの偏りを前提にした管理手法。
使える場面 具体的な使い方
小売・ECの在庫管理 商品別の出荷金額でランク分けし、Aランクは欠品させない発注頻度に、Cランクは在庫圧縮や取り扱い終了の検討候補にする
営業の顧客分析 顧客別の年間売上でABC分析し、Aランク顧客には定期訪問、Cランク顧客はメール中心の省力対応に切り替えて営業リソースを配分する
問い合わせ対応の改善 問い合わせを分類別に件数集計してパレート図にし、件数上位の分類からFAQや自動応答を整備して対応工数を削る
経費・購買の見直し 支出を費目別に並べて累積構成比を出し、金額の大きいAランク費目から順に値下げ交渉や契約見直しを進める
さらに詳しく学べるPython研修の詳細はこちら

PythonのABC分析まとめと次の一歩

pandasの基本操作だけで、在庫60品目のABC分析から4種類のグラフ生成までを実装できました。sort_valuescumsumpd.cutの3ステップさえ押さえれば、応用はいくらでも広がります。

ランクの配色を全図で統一する、パレート図に70%・90%の基準線を引くといった小さな工夫が、グラフの読みやすさを大きく左右するのも今回の実感です。

次の一歩としては、実データのCSV読み込み対応、ランクのしきい値を引数化する改造、月次データでのランク変動の追跡などが考えられます。まずはシード値やbinsを変えて、結果がどう動くか試してみてください。

さらに詳しく学べるPython研修の詳細はこちら

参考にした一次情報

  1. ^ pandas.cut — pandas公式リファレンス. https://pandas.pydata.org/docs/reference/api/pandas.cut.html, (参照26-07-17).
  2. ^ pandas.DataFrame.cumsum — pandas公式リファレンス. https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.cumsum.html, (参照26-07-17).
  3. ^ numpy.random.Generator.lognormal — NumPy公式リファレンス. https://numpy.org/doc/stable/reference/random/generated/numpy.random.Generator.lognormal.html, (参照26-07-17).
  4. ^ matplotlib.axes.Axes.twinx — Matplotlib公式リファレンス. https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.twinx.html, (参照26-07-17).

※内容は執筆時点のものです。ライブラリやサイトの仕様は変わる可能性があるため、公式ドキュメントもあわせてご確認ください。

ITやプログラミングに関するコラム


ITやプログラミングに関するニュース

ブログに戻る

コメントを残す

コメントは公開前に承認される必要があることにご注意ください。

企業・法人向けのIT・プログラミング・生成AI研修を探す、比較する - IT・プログラミングを知って学べるコネクトメディア CodeCampが提供するDX人材育成が可能なプログラミングやITが学べる公開講座 - IT・プログラミングを知って学べるコネクトメディア コードキャンプが提供する無料で学べるプログラミングスクール講座 - IT・プログラミングを知って学べるコネクトメディア コードキャンプDX人材育成研修 - IT・プログラミングを知って学べるコネクトメディア 3.5日の研修で、年間1,600時間の削減効果が見込まれる。東京きらぼしフィナンシャルグループのDX人材育成事例 - IT・プログラミングを知って学べるコネクトメディア 配属3ヶ月で30%の生産性向上を実現するいよぎんコンピュータサービスの新人研修に迫る - IT・プログラミングを知って学べるコネクトメディア 金融業界の業務効率化を加速するニッセイアセットマネジメントの生成AI×GAS活用研修事例 - IT・プログラミングを知って学べるコネクトメディア 【製造業のDX人材育成事例】デジタル人材の即戦力化を実現する、日本ガイシ株式会社の異動者向オンボーディング研修 - ITやプログラミングを知って学べるコネクトメディア フューチャーアーキテクト株式会社が実現した新入社員向けIT研修プログラムでタスクフォース制度が主体的な学びと成長を生み出す - IT・プログラミングを知って学べるコネクトメディア コードキャンプDX人材育成研修 - IT・プログラミングを知って学べるコネクトメディア コードキャンプIT・プログラミング研修事例/【IT新入社員研修】オンラインとオフラインの最適バランスを実現したFutureOneの導入事例 - IT・プログラミングを知って学べるコネクトメディア コードキャンプIT・プログラミング研修事例/【新入社員研修】柔軟なハイブリッド型Java研修で実現した新卒20名の成長と成果|サークレイス株式会社 - ITやプログラミングを知って学べるコネクトメディア コードキャンプIT・プログラミング研修事例/現場により近いところにデジタルを根付かせるDX基礎講座研修|株式会社ブリヂストン - ITやプログラミングを知って学べるコネクトメディア コードキャンプIT・プログラミング研修事例/業務の効率化・DX推進に向けたIT人材育成への第一歩|株式会社カナエ - ITやプログラミングを知って学べるコネクトメディア 企業・法人向けのIT・プログラミング研修 - ITやプログラミングを知って学べるコネクトメディア

新着記事

対象者別で探す

子供(小学生・中学生・高校生)向け
プログラミング教室検索する

子供(小学生・中学生・高校生)がロボットやプログラミング言語を学ぶことができるオフラインからオンラインスクールを検索、比較することが可能です。

子供(小学生・中学生・高校生)
プログラミング教室検索する

ITやプログラムなどの
最新情報を検索する

日々、新しいITやプログラミング言語の情報が流れていきますが、特定の情報を時系列でニュースやコラムを確認することができます。

ITやプログラムなどの
最新情報を検索する