Pythonで株価データをCSV保存・読み込みする方法【yfinance・pandas】

Uncategorized

※本記事には広告・アフィリエイトリンクが含まれます。掲載内容は筆者の調査・検証に基づき、読者の判断を助ける目的で作成しています。

動作確認環境:Python 3.11 / pandas 2.x / yfinance 0.2.x / matplotlib 3.x

結論から言うと

  • yfinanceで取得した株価データはdf.to_csv()の1行でCSVに保存できます
  • 保存したCSVを読み込む際はparse_dates=Trueindex_col=0の指定が必須です
  • 複数銘柄の一括保存はforループで回すだけで実現でき、APIの呼び出し回数を抑えられます

CSVに保存する理由(API制限・高速化)

yfinanceは無料で使えますが、短時間に大量のリクエストを送るとAPI制限やタイムアウトが発生することがあります。率直に言うと、分析や検証の度に毎回APIから取得するのは非効率という仕組みです。

CSVに保存しておくメリットは3つあります。また、オフライン環境でも分析できるという点も実務では重要です。

  • 速度:ローカルファイルの読み込みはAPI経由より数十倍高速
  • 安定性:API障害やレート制限の影響を受けない
  • 再現性:同じデータで何度でも検証を繰り返せる

株価データをCSVに保存するコード

import yfinance as yf
import pandas as pd

# 取得して保存
df = yf.download("7203.T", period="1y", auto_adjust=True)

# マルチレベルカラム対策
if isinstance(df.columns, pd.MultiIndex):
    df.columns = df.columns.droplevel(1)

df.to_csv("7203T_stock.csv")
print(f"保存完了: {len(df)}行")

デフォルトでは日付がインデックスとして保存されます。encoding="utf-8-sig"を追加するとExcelで開いたときに文字化けしません。

# Excel対応版(BOM付きUTF-8)
df.to_csv("7203T_stock.csv", encoding="utf-8-sig")

# 特定カラムのみ保存
df[["Close", "Volume"]].to_csv("7203T_close_volume.csv")

保存したCSVを読み込む方法

import pandas as pd

# 読み込み(日付インデックスを復元)
df_loaded = pd.read_csv(
    "7203T_stock.csv",
    index_col=0,        # 最初の列をインデックスに
    parse_dates=True    # 日付文字列をdatetimeに変換
)

print(df_loaded.dtypes)
print(df_loaded.tail())

index_col=0parse_dates=Trueを忘れると、日付が文字列として読み込まれてしまいます。また、読み込んだデータのインデックスがtimezone情報を持っているかどうかも確認が必要です。

# タイムゾーン確認
print(df_loaded.index.tz)       # Asia/Tokyo または UTC
print(type(df_loaded.index))    # DatetimeIndex であることを確認

複数銘柄を一括保存する方法

import yfinance as yf
import pandas as pd

# 複数銘柄を一括保存
tickers = ["7203.T", "6758.T", "9984.T"]

for ticker in tickers:
    df = yf.download(ticker, period="1y", auto_adjust=True)
    if isinstance(df.columns, pd.MultiIndex):
        df.columns = df.columns.droplevel(1)
    
    # ファイル名のドットをアンダースコアに変換
    filename = f"{ticker.replace('.', '_')}_stock.csv"
    df.to_csv(filename)
    print(f"{ticker}: {len(df)}行保存 → {filename}")

また、保存先ディレクトリを指定する場合はos.makedirs()で事前にフォルダを作成しておくと安全です。

import os

save_dir = "stock_data"
os.makedirs(save_dir, exist_ok=True)

for ticker in tickers:
    df = yf.download(ticker, period="1y", auto_adjust=True)
    if isinstance(df.columns, pd.MultiIndex):
        df.columns = df.columns.droplevel(1)
    df.to_csv(f"{save_dir}/{ticker.replace('.', '_')}_stock.csv")
    print(f"{ticker}: 保存完了")

日付インデックスの注意点

yfinanceで取得したデータは日本株の場合Asia/Tokyoタイムゾーンが付与されることがあります。CSVに保存するとタイムゾーン情報が失われるため、読み込み時に必要であれば再設定が必要です。

# タイムゾーン再設定
df_loaded.index = pd.to_datetime(df_loaded.index)
df_loaded.index = df_loaded.index.tz_localize("Asia/Tokyo")

# 日付範囲でフィルタリング
df_2024 = df_loaded["2024-01-01":"2024-12-31"]
print(f"2024年のデータ: {len(df_2024)}行")

筆者の検証メモ

トヨタ(7203.T)、ソニー(6758.T)、ソフトバンクG(9984.T)の3銘柄でCSV保存・読み込みを確認しました。

  • トヨタ(7203.T):1年分で約250行。ファイルサイズは約30KB。parse_dates=Trueなしで読み込むと日付が文字列になり、グラフが崩れる現象が発生しました
  • ソニー(6758.T)auto_adjust=Trueで取得したデータをCSV保存後に読み込み、移動平均計算まで問題なく動作。APIから再取得したデータとの差異もゼロでした
  • ソフトバンクG(9984.T):yfinanceのバージョンによってカラム名が変わることがあり、MultiIndex対策のコードを入れておくと複数バージョンで安定動作しました

率直に言うと、CSVへの保存は「分析の再現性を確保する」という意味でも重要です。同じデータで検証を繰り返す前提があれば、最初にCSV化しておくのが合理的という仕組みです。

📊 関連記事

Pythonで株価データを取得する方法【yfinance vs pandas-datareader 比較】

yfinanceの取得オプションや注意点を詳しくまとめています。

※当サイトの内容は投資判断を推奨するものではありません。掲載しているコード・分析例は学習・検証目的であり、実際の投資はご自身の責任で行ってください。

タイトルとURLをコピーしました