PBR(株価純資産倍率、Price Book-value Ratio)は、PER と並んでよく使われるバリュエーション指標です。本記事では PBR の定義・計算式・簿価の意味・「PBR < 1 = 割安」と単純に判断できない理由を整理し、pandas で複数銘柄を一括計算するコード例を示します。
目次
- PBR とは
- 簿価(BPS)とは何か
- 何のために使うか
- 「PBR < 1 = 割安」とは限らない理由
- 単一銘柄を計算する
- 複数銘柄を pandas で一括計算する
- 業種別の PBR 中央値を出す
- ROE と組み合わせて読む
- 過去の歪みに気をつける
PBR とは
PBR は「株価が、1 株あたり純資産の何倍で値付けされているか」を表す指標です。式は次の通りです。
BPS(Book-value Per Share)は、純資産(自己資本)を発行済株式数で割った値です。
たとえば株価 1500 円、BPS 1200 円なら、PBR = 1500 / 1200 = 1.25(倍)となります。
簿価(BPS)とは何か
BPS の元になる純資産は、会計上の帳簿に記録された価値 です。会社が持つ資産から負債を差し引いた残りで、株主に帰属する金額の 会計的な近似値 です。
ここで重要なのは、簿価が 時価とは限らない という点です。次のようなずれが起きます。
- 不動産の取得価額が古いまま残っており、現在の時価より大幅に低い(または高い)
- ブランド・特許・人材といった 無形の価値 は基本的に簿価に乗らない
- 減損処理のタイミング次第で、簿価が一時的に大きく動く
この「簿価 ≠ 時価」の構造が、PBR の解釈を難しくします。
何のために使うか
PBR は次のような場面で使います。
- 同業種内で「割安 / 割高」の感覚をつかむ
- 同じ銘柄の 過去の PBR 水準 との比較
- ROE と組み合わせて使う(PBR ≒ PER × ROE、#8-3「ROE / ROA で稼ぐ力を見る」)
- 赤字企業でも計算できる(BPS は通常正の値)
赤字でも計算できるのは PBR の利点です。PER は EPS が負だと使えません(#8-1「PER(株価収益率)を Python で計算する」)。
「PBR < 1 = 割安」とは限らない理由
「PBR が 1 倍を割っていれば、株価は会社の解散価値より低い」という説明をよく目にします。これは形式的には正しいですが、実務的には 割安と決めつけられない 理由があります。
- 解散できないことが多い: 上場会社が即座に解散して純資産を株主に分配する想定は現実的ではない
- 資産の処分価値は簿価とずれる: 在庫・設備の売却価格は簿価より下がることが多い
- 継続的に赤字を出している: PBR が 1 倍未満でも、純資産が毎年減っていく会社は割安と言えない
- ROE が低い: 株主資本を増やせない会社は、市場が相応に低く評価する
特に 継続的赤字 や ROE が極端に低い 銘柄では、PBR < 1 が 割安ではなく構造的な問題 の反映であるケースが多くあります。
単一銘柄を計算する
サンプル値で 1 銘柄を計算する例です。
def pbr(price: float, bps: float) -> float | None: """株価と BPS から PBR を返す。BPS が 0 / 負の場合は None。""" if bps is None or bps <= 0: return None return price / bps
print(pbr(1500, 1200)) # 1.25print(pbr(1500, -100)) # None (債務超過)print(pbr(1500, 0)) # None純資産がマイナス(債務超過)の場合は計算不能扱いにしておくのが安全です。
複数銘柄を pandas で一括計算する
J-Quants の財務データから純資産と発行済株式数を取得した想定で、pandas で計算します。
import numpy as npimport pandas as pd
df = pd.DataFrame({ "Code": ["1301", "1302", "1303", "1304", "1305"], "CoName": ["サンプル商事001", "サンプル商事002", "サンプル商事003", "サンプル商事004", "サンプル商事005"], "C": [2900, 1500, 13000, 4900, 600], "Eq": [27_000_000_000_000, 13_000_000_000_000, 7_500_000_000_000, 3_300_000_000_000, 3_400_000_000_000], # 純資産(円) "shares": [13_400_000_000, 12_400_000_000, 1_240_000_000, 2_020_000_000, 1_607_000_000], # 発行済株式数(株)})
df["BPS"] = df["Eq"] / df["shares"]df["pbr"] = np.where(df["BPS"] > 0, df["C"] / df["BPS"], np.nan)df = df.assign(BPS=df["BPS"].round(2), pbr=df["pbr"].round(2))print(df[["Code", "CoName", "C", "BPS", "pbr"]])np.where で BPS が正の銘柄だけ計算し、それ以外は NaN にしておくと、後段の集計で扱いやすくなります。なお、上のサンプル値は説明のための 架空の概算 です。実値は J-Quants API の財務データと株価データから取得します(#6-5「日次株価四本値を取得する (/equities/bars/daily)」 / #6-6「財務情報を取得する (/fins/summary)」)。
業種別の PBR 中央値を出す
PBR は業種で水準が大きく違うため、比較するときは業種で揃えます。
df["S33Nm"] = ["輸送用機器", "銀行業", "電気機器", "化学", "電気・ガス業"]
sector_pbr = ( df.dropna(subset=["pbr"]) .groupby("S33Nm")["pbr"] .agg(["median", "mean", "count"]) .round(2) .sort_values("median"))print(sector_pbr)中央値を併記すると、外れ値の影響を抑えた比較ができます。
ROE と組み合わせて読む
PBR は ROE(自己資本利益率)とセットで読むと、解釈が安定します。式の上では次の関係があります。
つまり、ROE が高い会社ほど PBR は高くなる傾向があります。PBR が低い銘柄を見つけたときは、ROE が低くないかをセットで確認します(詳細は#8-3「ROE / ROA で稼ぐ力を見る」)。
| 解釈の枠組み | PBR 低 | PBR 高 |
|---|---|---|
| ROE 高 | 過小評価の可能性 | 成長期待が強い |
| ROE 低 | 構造的な低評価(割安と限らない) | バブル的な過大評価の可能性 |
PBR と ROE の 4 象限で見ると、単純な PBR の高低だけよりも解像度が上がります。
過去の歪みに気をつける
PBR は 過去の決算時点の純資産 を使います。次の点に注意します。
- 直近で 増資 / 自社株買い があると BPS が大きく動く
- 直近で 減損損失 が出ると純資産が減り、PBR が一時的に上がる
- 会計基準変更(IFRS / 日本基準)で純資産が増減することがある
複数年の PBR を時系列で見ると、こうした歪みに気づきやすくなります。
生成AI へのプロンプト例
PBR と ROE の 4 象限プロットを書きたい場合の例です。
入力 DataFrame に次の列があります(銘柄識別列は J-Quants API に準拠)。- Code (str)- CoName (str)- S33Nm (str)- pbr (float, 計算不能な銘柄は NaN)- roe (float, 単位は % で 0〜30 程度)
依頼:- PBR を x 軸、ROE を y 軸とした散布図を描く- 業種ごとに色分け- 各点に銘柄名のラベルを付ける(重なりは許容、annotate のみ)- pbr=1, roe=8 で水平線・垂直線を引き 4 象限化- 図のタイトル・軸ラベルは日本語
要件: pandas 2.2 系 + matplotlib(seaborn は使わない)。関数化し、docstring は日本語。まとめ
- PBR は「株価が BPS の何倍か」。BPS は会計上の純資産 / 発行済株式数
- 簿価は時価ではない。無形価値や時価とのずれが解釈を難しくする
- PBR < 1 は必ずしも割安ではない。継続赤字・低 ROE では構造的な低評価のケースが多い
- ROE と組み合わせた 4 象限で読むと解像度が上がる