見出し画像

M365の配布リストをPowerShellで書き出し、Pythonで階層構造の可視化(加工編)

前回の記事でPowerShellを使って生成されたエクセルファイルを、Pythonを使って加工します。前回の記事は以下よりご確認ください。

エクセルが正しく生成されていることが確認できたら続けて以下のコードをPythonで実行してください。

Python

※ 必要なモジュールは適宜インストールしてください。

import glob 
import pandas as pd
import datetime
from tqdm import tqdm

print('配布グループの構造状態を可視化中')

file = glob.glob('配布グループ一覧_*.xlsx')
df = pd.read_excel(file[-1])
df.insert(2, '削除', 0)

num_parent_ml = 1
k = 0
# 親MLが空白じゃない行の数が0になるまで繰り返す
while num_parent_ml>0 :
    df.insert(0, 'ML_'+str(k+3), '')    # 親MLの列を追加。
    last_row = len(df)                  # 行数を取得
    for i in tqdm(range(last_row)):
        # 基点MLが空白じゃない場合(kが1以上のとき)
        if df['ML_'+str(k+2)].iloc[i] != '':
            for j in range(last_row):
                # 基点MLと同じMLがサブMLにある場合
                if df['ML_'+str(k+2)].iloc[i] == df['ML_1'].iloc[j]:
                    # i行の親MLにj行のML_2を入力
                    if df['ML_'+str(k+3)].iloc[i] == '':
                        df.loc[df.index[i], 'ML_'+str(k+3)] = df['ML_2'].iloc[j]
                    else:
                        df_extra = df.iloc[[i]].copy()  # 別のDFにi行をコピー
                        df_extra.loc[df_extra.index[0], 'ML_'+str(k+3)] = df['ML_2'].iloc[j]
                        df = pd.concat([df, df_extra])  # DFを結合
                    df.loc[df.index[j], '削除'] = 1
    
    df.drop_duplicates(inplace=True)        # 重複した行を削除
    df.reset_index(drop=True, inplace=True) # インデックスをリセット

    num_parent_ml = (df['ML_'+str(k+3)] != '').sum()    # 親MLが空白じゃない行の数を算出
    k += 1

df = df[df['削除'] == 0]    # 削除フラグが0の行だけにする
df.drop(columns='削除', inplace=True) # 削除列を削除

# 各行の空白を削除して左詰め
columns_name = df.columns   # 列名を取得
# df = df.apply(lambda r: r.drop_duplicates().reset_index(drop=True), axis=1)
def drop(r):
    r = r.drop_duplicates().reset_index(drop=True)
    return r
df = df.apply(drop, axis=1)
df.columns = columns_name   # 列名を設定

df.drop(columns='ML_'+str(k+2), inplace=True) # 最初の列を削除
for i in range(len(df.columns)):
    df = df.sort_values(df.columns.tolist())  # 並び替え
df.reset_index(drop=True, inplace=True) # インデックスをリセット

now = datetime.datetime.now()
fix_filename = '配布グループ階層一覧_' + now.strftime('%Y%m%d_%H%M%S') + '.xlsx'
df.to_excel(fix_filename, index=False)

※ 本コードを利用する場合は必ず以下の免責事項をご確認ください。

おわり

見ての通り、繰り返しを三重にかけていので結構時間がかかります・・・。スペックがIntel Core i5 3GHz / RAM 16GBのPCで、仕上がり7列2500行ぐらい表を作成するのに3分半ぐらい。

いずれ高速化させたいと考えていますが、取り急ぎ業務で使用する際はコーヒータイムの並行処理で効率化させています。

おまけ

サビコラボ。

この記事が気に入ったらサポートをしてみませんか?