本記事では学習のアウトプットとして、『Python実践データ分析100本ノック』に書かれている各ノックのコードのうち、難解と思われる部分の意味を解説していきます。 「本に書かれている解説だけでは理解が難しい(;一_一)」と感じた方、この記事を読んで理解の一助となれば幸いです。
Python実戦データ分析100本ノックは、データの集計や分析のためのpandasや。グラフ描画に使用するmatplotlib、機械学習を行うためのscikit-learnなど、データ分析に欠かせない要素を実際に自分で手を動かしながら学ぶことができる本です。
私自身はpython初心者で、pythonを触ったことがありませんでしたが、自ら手を動かしてpythonを学習したいと思いこちらの本で学習しました。よければ手に取っていただきたいです(・ω・)ノ。
今回は第14回として、ノック63-65をやっていきます。
追記:現在第二版が2022年6月に出版されています。
本記事は第1版の内容の解説です。
第二版の解説記事もいずれ書かせていただこうと思っていますので今しばしお待ちください!
第7章 ロジスティクスネットワークの最適設計を行う10本ノック
第7章では、最適化計算を行うためのライブラリを用いて、最適化問題に取り組みます。そして、ノック51-60で学習したネットワーク可視化を実施することで、最適化計算の妥当性を確認します。
ノック63:最適輸送ルートが制約条件内に収まっているかどうかを確認しよう
ここでは、ノック26-30で学習したフラグを用いて、最適計算を行った結果の輸送ルートが制約条件を満たしているかどうかを確認するための関数を定義します。
import pandas as pd
import numpy as np
#データ読み込み
#demand.csvは工場の製品生産量に対する需要を記載した1行×4列(F1~F4)のデータです。
df_demand=pd.read_csv('demand.csv')
#supply.csvは倉庫が供給可能な部品数の上限を記載した1行×3列(W1~W3)のデータです。
df_supply=pd.read_csv('supply.csv')
#制約条件計算関数
#需要側
def condition_demand(df_tr,df_demand):
#np.zeros()関数は0で初期化されたndarrayを生成します。
#第一引数に生成したい配列のshape(何行×何行か)を指定します。
#len(.columns)でdf_demandの列(F1~F4)数4回分操作を繰り返します。
#つまり、1行×4列で各要素の値が0である配列を作成します。
flag=np.zeros(len(df_demand.columns))
for i in range(len(df_demand.columns)):
#総輸送コストの計算結果が書かれているdf_trから、需要データを取り出し和を計算しています。
temp_sum=sum(df_tr[df_demand.columns[i]])
#temp_sumがF1~F4の各工場の需要以上である場合、各列(各工場に対応しています)flagを1に変換します。
if(temp_sum>=df_demand.iloc[0][i]):
flag[i]=1
return flag
#供給側
def condition_supply(df_tr,df_supply):
#len(.columns)でdf_supplyの列(W1~W3)数3回分操作を繰り返します。
#つまり、1行×3列で各要素の値が0である配列を作成します。
flag=np.zeros(len(df_supply.columns))
for i in range(len(df_supply.columns)):
#総輸送コストの計算結果が書かれているdf_trから、供給データを取り出し和を計算しています。
temp_sum=sum(df_tr.loc[df_supply.columns[i]])
#temp_sumがW1~W3の各倉庫の需要以上である場合、各列(各倉庫に対応しています)flagを1に変換します。
if temp_sum<=df_supply.iloc[0][i]:
flag[i]=1
return flag
print("需要条件計算結果:"+str(condition_demand(df_tr_sol,df_demand)))
print("供給条件計算結果:"+str(condition_supply(df_tr_sol,df_supply)))
ノック64:生産計画に関するデータを読み込んでみよう
これまでと同様にデータ読みこみを行います。(解説は省略させていただきます。)
ノック65:利益を計算する関数を作ってみよう
輸送最適化問題を解くのと同じ要領で生産の最適化問題を解き、最適化を行います。
まずは、利益を計算する関数を定義します。
def product_plan(df_profit, df_plan):
profit = 0
#df_profitは製品1と製品2の利益を記載した2行×1列(製品1~製品2)のデータです。
#len(.columns)でdf_profitの列数2回分操作を繰り返します。
for i in range(len(df_profit.columns)):
#df_planは製品の生産量を記載した2行×1列(製品1~製品2)のデータです。
#len(.columns)でdf_planの列数2回分操作を繰り返します。
for j in range(len(df_plan.columns)):
#df_profitとdf_planのデータから、それぞれの製品の利益と生産量を取り出し、積の和を計算しています。
profit += df_profit.iloc[i][j] * df_plan.iloc[i][j]
return profit
print('総利益:' +str(product_plan(df_profit, df_plan)))
利益を計算する関数を作成できました。
ここまでで、ノック63-65は完了です。お疲れ様でした。
最適化した輸送ルートが制約条件を満たしているかを確認する関数と、利益を計算する関数を定義しました。