ROE(自己資本利益率)と ROA(総資産利益率)は、企業の「稼ぐ力」を見るための代表的な指標です。本記事では両者の定義・違い・デュポン分解の入口を整理し、pandas で複数銘柄を一括計算する例を示します。

目次

  1. ROE とは
  2. ROA とは
  3. ROE と ROA の関係
  4. デュポン分解の入口
  5. 単一銘柄を計算する
  6. 複数銘柄を pandas で一括計算する
  7. デュポン分解を pandas で計算する
  8. ROE / ROA を読むときの注意

ROE とは

ROE(Return on Equity)は「株主資本(純資産)が、年間でどれだけ純利益を生み出したか」を表します。

ROE=純利益自己資本(純資産)×100(%)\text{ROE} = \frac{\text{純利益}}{\text{自己資本(純資産)}} \times 100\,(\%)

たとえば純利益 100 億円、自己資本 1,000 億円なら、ROE = 10%。株主から預かった資本に対して、年間 10% のリターンを稼いだという意味です。

ROE が高いほど 株主資本を効率よく利益に変換できている と解釈できます。投資家視点から重要な指標とされる理由です。

ROA とは

ROA(Return on Assets)は「会社の総資産が、年間でどれだけ純利益を生み出したか」を表します。

ROA=純利益総資産×100(%)\text{ROA} = \frac{\text{純利益}}{\text{総資産}} \times 100\,(\%)

総資産は自己資本だけでなく、借入金などの負債も含みます。ROA が高いほど、借入を含めた事業全体 の収益効率が高いことを意味します。

ROE と ROA の関係

両者の関係は次の式で書けます。

ROE=ROA×総資産自己資本\text{ROE} = \text{ROA} \times \frac{\text{総資産}}{\text{自己資本}}

「総資産 / 自己資本」を 財務レバレッジ と呼びます。借入が多いほどレバレッジは大きく、ROE は ROA より大きくなります。同じ ROA でも、レバレッジが高い会社の ROE は 見かけ上高く なる構造です。

「ROE が高い銘柄を選ぶ」場合、財務レバレッジで稼いでいるのか、本業の収益力で稼いでいるのかを区別する必要があります。

デュポン分解の入口

ROE は次のように 3 つに分解できます。これを デュポン分解 と呼びます。

ROE=純利益売上高×売上高総資産×総資産自己資本\text{ROE} = \frac{\text{純利益}}{\text{売上高}} \times \frac{\text{売上高}}{\text{総資産}} \times \frac{\text{総資産}}{\text{自己資本}}

それぞれの項に名前があります。

  • 第 1 項: 売上高純利益率(Net Profit Margin)
  • 第 2 項: 総資産回転率(Asset Turnover)
  • 第 3 項: 財務レバレッジ(Equity Multiplier)

ROE が同じでも、3 項の内訳が違う会社は 稼ぎ方 が違います。たとえば次のように対比できます。

業態利益率回転率レバレッジ
高級ブランド高い低い中程度
ディスカウントストア低い高い中程度
銀行低い低い高い

「同じ ROE 10%」でも、内訳が違えば事業の性質も違います。

単一銘柄を計算する

サンプル値で計算する例です。

def roe(net_income: float, equity: float) -> float | None:
"""ROE(%)を返す。equity が 0 / 負の場合は None。"""
if equity is None or equity <= 0:
return None
return net_income / equity * 100
def roa(net_income: float, assets: float) -> float | None:
if assets is None or assets <= 0:
return None
return net_income / assets * 100
print(round(roe(100, 1000), 2)) # 10.0
print(round(roa(100, 5000), 2)) # 2.0

ROE は数十%、ROA は数%が現実的な水準です。ROA が ROE を上回る場合は、無借金または資産構成に何か特殊な事情がある可能性があり、確認が必要です。

複数銘柄を pandas で一括計算する

財務データの DataFrame を入力に取る前提です。

import numpy as np
import pandas as pd
df = pd.DataFrame({
"Code": ["1301", "1302", "1303", "1304", "1305"],
"CoName": ["サンプル商事001", "サンプル商事002", "サンプル商事003",
"サンプル商事004", "サンプル商事005"],
"NP": [4_900_000_000_000, 1_500_000_000_000, 970_000_000_000,
700_000_000_000, -200_000_000_000],
"Eq": [27_000_000_000_000, 13_000_000_000_000, 7_500_000_000_000,
3_300_000_000_000, 6_000_000_000_000],
"TA": [70_000_000_000_000, 380_000_000_000_000, 30_000_000_000_000,
4_500_000_000_000, 36_000_000_000_000],
})
df["roe"] = np.where(df["Eq"] > 0, df["NP"] / df["Eq"] * 100, np.nan)
df["roa"] = np.where(df["TA"] > 0,
df["NP"] / df["TA"] * 100, np.nan)
df = df.assign(roe=df["roe"].round(2), roa=df["roa"].round(2))
print(df[["Code", "CoName", "roe", "roa"]])

赤字銘柄(サンプル商事005)は ROE / ROA が になります。負を含めて表示するか、フィルタで除外するかは目的に応じて決めます。

なお、上記サンプル値は説明用の 架空の概算 です。実値は J-Quants API の財務データから取得します(#6-6「財務情報を取得する (/fins/summary)」)。

デュポン分解を pandas で計算する

3 項に分解した値を列として持っておくと、後の比較が楽になります。

df["Sales"] = [40_000_000_000_000, 9_000_000_000_000, 13_000_000_000_000,
2_500_000_000_000, 6_500_000_000_000] # 売上高
df["margin"] = df["NP"] / df["Sales"] * 100
df["turnover"] = df["Sales"] / df["TA"]
df["leverage"] = df["TA"] / df["Eq"]
df["roe_check"] = df["margin"] * df["turnover"] * df["leverage"] / 100
# roe_check が roe と概ね一致することを確認
cols = ["Code", "CoName", "margin", "turnover", "leverage", "roe", "roe_check"]
print(df[cols].round(3))

roeroe_check の差が大きい場合、計算上の丸め誤差・データの粒度ずれが疑われます。

ROE / ROA を読むときの注意

ROE / ROA を実用するときに踏まえたいポイントです。

  • 単年で評価しない: 特別損益で利益が大きくぶれる年がある。3〜5 年の平均で見る
  • 業種で水準が違う: 銀行業はレバレッジが高く ROE が高めに見える
  • 過剰なレバレッジは脆さ: 高 ROE が借入依存の場合、金利上昇 / 業績悪化で大きく崩れる
  • 自社株買いで ROE が上がる: 純資産を減らすことでも ROE は上昇する。継続的な収益力とは別の話

「ROE 8% が日本のひとつの目安」と言われることがありますが、業種や事業ステージで適切な水準は変わります。

生成AI へのプロンプト例

3 期分のデュポン分解を時系列で並べたい場合の例です。

入力 DataFrame に次の列があります(財務項目は J-Quants API に準拠)。
- Code (str)
- fiscal_year (int): 2022, 2023, 2024
- NP (float)
- Sales (float)
- TA (float)
- Eq (float)
依頼:
- Code × fiscal_year ごとに margin, turnover, leverage, roe, roa を計算
- 戻り値は元の列に上記指標を追加した DataFrame
- Eq <= 0 / TA <= 0 の場合は当該指標を NaN
要件: pandas 2.2 系。関数化し、docstring は日本語。

まとめ

  • ROE は株主資本に対する利益率、ROA は総資産に対する利益率
  • ROE = ROA × 財務レバレッジ。レバレッジで見かけの ROE が上がる構造に注意
  • デュポン分解で「利益率 / 回転率 / レバレッジ」に分けると稼ぎ方が見える
  • 単年でなく複数年で見る。業種で水準が違うことも踏まえる