PythonでExcel操作:カテゴリ集計値を別シートにグラフ出力用のレイアウトで転記する

勉強系(Python/Excel/統計学/その他)

全体まとめページは↓より。

前提

以下の内容で出力した、複数カテゴリの集計ファイルをインプットとして利用する。

↓読み込みファイル

やりたいこと

複数カテゴリの集計値を、グラフが出力できるレイアウトに整える。
まず別シートを作り、そこに主カテゴリと副カテゴリのクロス集計表形式で出力する。
↓読み込みファイル

↓別シートにこのレイアウトで出力したい。

フォルダ構成

VSCodeで実行するときはprg配下を開いてpyファイルを作り実行する。

実装

55行目からが今回のポイント。

メインカテゴリと副カテゴリのリストを先に作り、2つのリストでforをネストして集計行を処理していく。集計行の値が0でない(実際の集計値である)場合、該当するメインカテゴリと副カテゴリが位置するクロス集計表のセルにそのまま転記する。

import os
import openpyxl
from operator import itemgetter

#辞書リストの作成関数
def make_shipment(sh):
    shipment_list = []
    for row in sh.iter_rows():
        if row[0].row == 1:
            header_cells = row
        else:
            row_dic = {}
            for v, k in zip(header_cells, row):
                row_dic[v.value] = k.value
            shipment_list.append(row_dic)
    return shipment_list

#項目リスト
collist = ["index","行き先","目的","目的合計(行き先別)"]

#ファイル名を入力させる
print("ファイル名を入力:")
filename = input()

#読み込みファイルパスを作成
infile_path = os.path.join("..\indata" , filename)

#読み込みファイルからオブジェクトを生成
iwb = openpyxl.load_workbook(infile_path)
ish = iwb.active

#出力ファイルオブジェクトを生成
owb = openpyxl.Workbook()
osh = owb.active

#出力ファイルパスを作成
outfile_path = os.path.join("..\outdata", filename)

#辞書リストを作成
shipment_list = make_shipment(ish)

#転記先ヘッダ処理
for col in range(len(collist)):
    osh.cell(1,col+1).value = collist[col]

#転記処理
list_row = 1
for dic in shipment_list:
    list_row += 1
    for col in range(len(collist)):
        colname = collist[col]
        osh.cell(list_row,col+1).value = dic[colname]
        col += 1

#ここから別シートへの転記処理
#出力ファイルに新しいシートを作成
osh = owb.create_sheet()

#サマリ転記処理
#1.shipment_listからカテゴリリストと副カテゴリリストを作る
category = "行き先"
category_list = []
old_key = ""
category_list_no = 1

for dic in shipment_list:
    if old_key == "":
        old_key = dic[category]

    if old_key != dic[category]:
        category_list.append(old_key)
        old_key = dic[category]

    #最終行処理
    if category_list_no == len(shipment_list):
        category_list.append(old_key)
    
    category_list_no += 1

category_sub = "目的"
shipment_list_sub = sorted(shipment_list, key = itemgetter(category_sub))

category_sub_list = []
old_sub_key = ""
category_list_no = 1

for dic in shipment_list_sub:
    if old_sub_key == "":
        old_sub_key = dic[category_sub]

    if old_sub_key != dic[category_sub]:
        category_sub_list.append(old_sub_key)
        old_sub_key = dic[category_sub]

    #最終行処理
    if category_list_no == len(shipment_list_sub):
        category_sub_list.append(old_sub_key)

    category_list_no += 1

#2.ガワの転記処理
#メインカテゴリ
# ヘッダ
osh.cell(1,1).value = category

# メインカテゴリを1列目に縦に並べて配置
list_row = 1
for n in category_list:
    list_row += 1
    osh.cell(list_row,1).value = n

#副カテゴリ
# 副カテゴリを1行目に横に並べて配置
list_col = 1
for n in category_sub_list:
    list_col += 1
    osh.cell(1,list_col).value = n

#3.中身の転記処理

#集計値列を指定
sum_category = "目的合計(行き先別)"

for dic in shipment_list:
    list_row = 1
    for n in category_list:
        list_row += 1
        #メインカテゴリが一致したら、次に副カテゴリの一致を探す
        if dic[category] == n:
            list_col = 1
            for k in category_sub_list:
                list_col += 1
                if dic[category_sub] == k:
                    #集計値列の実際の値が入っている場合、その値を対応するセルに転記する
                    if dic[sum_category] > 0:
                        osh.cell(list_row, list_col).value = dic[sum_category]

#出力ファイルを保存
owb.save(outfile_path)

出力結果

A列に縦方向にメインカテゴリ、1行目に横方向に副カテゴリを並べたクロス集計表が転記されている。

↓出力ファイル

以上

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