現在の見出し:3.1節:Excel出力システムの構築
見出し一覧
- 3.1節:Excel出力システムの構築
- - pd.ExcelWriter()による複数シート出力機能の実装
- - openpyxl.chart.LineChart()による売上推移グラフ作成機能の追加
【PR】『Python』を学べる企業・個人向けのプログラミングコース
pd.ExcelWriter()による複数シート出力機能の実装
前節(第2章 2.2節)で作成したコードを基盤として、pd.ExcelWriter()による複数シートの出力機能を実装します。現在の分析機能では、地域別・商品別の詳細な集計結果を得ることができていますが、これらの結果をExcel形式で保存・共有する手段がないため、ビジネス現場での活用が困難な状況です。
pd.ExcelWriter()を使用することで、複数のDataFrameを1つのExcelファイル内の個別シートとして出力できます。with文を使用した安全なファイル操作により、処理中にエラーが発生してもファイルが適切に閉じられます。各分析結果には分かりやすいシート名を設定し、構造化されたレポートを作成できます。
機能 | 役割 | メリット |
---|---|---|
pd.ExcelWriter() | 複数シートのExcelファイル作成 | 分析結果を整理して一元管理一元管理は企業や組織内で、情報システムやデータベース、アプリケーションなどを統一的に管理する手法です。 |
engine='openpyxl' | .xlsx形式での出力指定 | 現代的なExcel形式で保存 |
os.makemakeはソフトウェア開発でビルドプロセスを自動化するツールで、変更ファイルのみ再コンパイルし効率的なビルドを実現します。dirs() | 出力ディレクトリの自動作成 | フォルダ不存在エラーを防止 |
sheet_name | 各シートに分かりやすい名前を設定 | 内容が一目で判別可能 |
create_excel_report関数関数は一定の処理をまとめたプログラムの塊です。を新規追加することで、Excel出力処理を独立して管理します。os.path.dirname()で出力パスパスはファイルやディレクトリの場所を示すために使われる言葉です。からディレクトリ部分を抽出し、exist_ok=Trueパラメータにより既存ディレクトリでもエラーにならない安全な処理を実現します。その結果、地域別売上と商品別推移の分析結果について、それぞれ専用シートに保存して見やすいレポート形式で提供できます。
# コード
import pandas as pd
import os
def load_sales_data(filepath):
"""売上データの読み込み"""
if not os.path.exists(filepath):
print(f"エラー: ファイルが見つかりません - {filepath}")
return None
df = pd.read_excel(filepath)
print(f"データ読み込み完了: {len(df)}行, {len(df.columns)}列")
print("データ構造:")
print(df.head())
return df
def preprocess_data(df):
"""データ前処理"""
if df is None:
return None
print(f"元データ: {len(df)}行")
# 日付変換
df['Date'] = pd.to_datetime(df['Date']).dt.strftime("%Y-%m")
print("日付変換完了")
# 欠損値除去
original_rows = len(df)
df = df.dropna()
print(f"欠損値除去: {original_rows - len(df)}行削除")
print("処理済みデータ:")
print(df.head())
return df
def analyze_basic_sales(df):
"""基本売上分析"""
if df is None:
return None
# 商品・地域リスト抽出
products = sorted(df['Product'].unique())
areas = sorted(df['Area'].unique())
print(f"商品数: {len(products)}")
print(f"地域数: {len(areas)}")
print(f"商品リスト: {products}")
print(f"地域リスト: {areas}")
# 月別商品別集計
monthly_product_sales = df.groupby(['Date', 'Product'])['Price'].sum().reset_index()
print("\n月別商品別売上:")
print(monthly_product_sales.head(10))
return {
'products': products,
'areas': areas,
'monthly_product': monthly_product_sales
}
def create_pivot_analysis(df, basic_results):
"""ピボット分析"""
if df is None or basic_results is None:
return basic_results
# ピボットテーブル作成(月×地域)
pivot_table = pd.pivot_table(df,
index='Date',
columns='Area',
values='Price',
aggfunc='sum',
fill_value=0)
print("\n地域別売上ピボットテーブル:")
print(pivot_table)
# 商品別売上推移
product_trend = df.groupby(['Date', 'Product'])['Price'].sum().unstack(fill_value=0)
print("\n商品別売上推移:")
print(product_trend)
# 既存結果に新しい分析結果を追加
basic_results['pivot_table'] = pivot_table
basic_results['product_trend'] = product_trend
return basic_results
def create_excel_report(analysis_results, output_path):
"""Excel形式の分析レポート作成"""
if analysis_results is None:
print("分析結果がありません")
return False
os.makedirs(os.path.dirname(output_path), exist_ok=True)
# 基本出力
with pd.ExcelWriter(output_path, engine='openpyxl') as writer:
analysis_results['pivot_table'].to_excel(writer, sheet_name='地域別売上')
analysis_results['product_trend'].to_excel(writer, sheet_name='商品別推移')
print(f"Excel基本出力完了: {output_path}")
return True
# メイン処理
def main():
filepath = "sample.xlsx"
output_path = "output/sales_report.xlsx"
df = load_sales_data(filepath)
if df is not None:
print("読み込み成功!")
processed_df = preprocess_data(df)
if processed_df is not None:
print(f"最終データ: {len(processed_df)}行")
print("データ型:")
print(processed_df.dtypes)
analysis_results = analyze_basic_sales(processed_df)
if analysis_results:
print(f"\n基本分析完了 - 商品数: {len(analysis_results['products'])}")
full_results = create_pivot_analysis(processed_df, analysis_results)
print(f"ピボット分析完了 - 地域数: {len(full_results['areas'])}")
# Excel出力の実行
if create_excel_report(full_results, output_path):
print("レポート作成完了!")
else:
print("読み込み失敗")
if __name__ == "__main__":
main()
# 実行結果
データ読み込み完了: 5行, 4列
データ構造:
Product Area Date Price
0 ProductA Tokyo 2024-01-15 1000
1 ProductB Osaka 2024-01-16 1500
2 ProductC Tokyo 2024-01-17 2000
3 ProductA Nagoya 2024-01-18 1200
4 ProductB Tokyo 2024-01-19 1800
読み込み成功!
元データ: 5行
日付変換完了
欠損値除去: 0行削除
処理済みデータ:
Product Area Date Price
0 ProductA Tokyo 2024-01 1000
1 ProductB Osaka 2024-01 1500
2 ProductC Tokyo 2024-01 2000
3 ProductA Nagoya 2024-01 1200
4 ProductB Tokyo 2024-01 1800
最終データ: 5行
データ型:
Product object
Area object
Date object
Price int64
dtype: object
商品数: 3
地域数: 3
商品リスト: ['ProductA', 'ProductB', 'ProductC']
地域リスト: ['Nagoya', 'Osaka', 'Tokyo']
月別商品別売上:
Date Product Price
0 2024-01 ProductA 2200
1 2024-01 ProductB 3300
2 2024-01 ProductC 2000
基本分析完了 - 商品数: 3
地域別売上ピボットテーブル:
Area Nagoya Osaka Tokyo
Date
2024-01 1200 1500 4800
商品別売上推移:
Product ProductA ProductB ProductC
Date
2024-01 2200 3300 2000
ピボット分析完了 - 地域数: 3
Excel基本出力完了: output/sales_report.xlsx
レポート作成完了!
行数 | 種別 | コード | 解説 |
---|---|---|---|
88行目 | 新規 | def create_excel_report(analysis_results, output_path): |
Excel形式の分析レポート作成専用関数を定義します。分析結果と出力パスを受け取って構造化されたExcelファイルを作成します。 |
94行目 | 新規 | os.makedirs(os.path.dirname(output_path), exist_ok=True) |
出力ディレクトリが存在しない場合に自動作成します。exist_ok=Trueにより既存ディレクトリでもエラーにならず安全に処理できます。 |
97行目 | 新規 | with pd.ExcelWriter(output_path, engine='openpyxl') as writer: |
ExcelWriter オブジェクトオブジェクトはプログラムの要素の一つで、データとその操作手段を一つにまとめたものです。を作成してwith文で安全に管理します。openpyxlエンジンにより.xlsx形式での出力が可能になります。 |
98行目 | 新規 | analysis_results['pivot_table'].to_excel(writer, sheet_name='地域別売上') |
地域別ピボットテーブルを専用シートに出力します。sheet_nameパラメータで分かりやすいシート名を設定します。 |
99行目 | 新規 | analysis_results['product_trend'].to_excel(writer, sheet_name='商品別推移') |
商品別推移データを別シートに出力して、分析結果を整理された形式で保存します。各分析軸を独立したシートで管理できます。 |
127行目 | 新規 | if create_excel_report(full_results, output_path): |
Excel出力関数を呼び出して分析結果をファイルに保存します。戻り値でExcel作成の成否を判定して後続処理を制御します。 |