見出し画像

【プログラミング初心者】が売上を予測してみました (vol.4:データ整理編)

この記事は、週毎の売上分析、予測に気象庁のデータを加えることで、予測精度が上がるかどうかをまとめたものです。
内容は2部構成になっています。
vol.4 : データ整理編
vol.5 : モデル作成編 / 線形重回帰モデル・LSTMモデル
です。

これまでに
「【プログラミング初心者】が売上を予測してみました」
では週毎の売上分析・予測を、
vol.1 : データ整理編
vol.2 : 時系列解析編
vol.3 : 回帰編
3部構成でまとめており、

「【プログラミング初心者】が在庫を予測してみました」
では在庫状況を分析し、未来の在庫を予測しています。

今回は「【プログラミング初心者】が売上を予測してみました」
のvol.1〜vol.3 でまとめた週毎の売上分析・予測を改良し、気象庁のデータを加えることで、予測の精度が上がるか検証します。
今回は「Vol.4 : データ整理編」です。


【売上データクレンジング・成形】

売り上げexcelデータの読み込み

まずは2018年から2020年までの3年分の週毎の売上データを読み込んでいきます。
試しに2018年度 MD1週のデータを表示します。

import pandas as pd
filepass="2018年度売上週報/MD1週売上週報.xlsx"
df= pd.read_excel("/content/drive/MyDrive/2018年度売上週報2/MD1週売上週報.xlsx")
df = df.iloc[:,1:]
df.head(10)

スクリーンショット 2021-05-23 13.48.07

箇所を指定して再度表示します。

df2=df[4:6]
df2

スクリーンショット 2021-05-23 13.49.27

'zMN'店舗のデータだけを抽出します。

targetname=['zWM']
columns_name=df2.columns[1]
df2.columns=["Unnamed: 0", "tar",	"Unnamed: 2",	"MD1週",	"週実績",	"Unnamed: 5",	"Unnamed: 6",	"Unnamed: 7",	"Unnamed: 8","Unnamed: 9"]
df2= df2.query("tar in @targetname")
df2

スクリーンショット 2021-05-23 14.14.36

1列目は不要なので、削除します。

df3=df2.drop("Unnamed: 0", axis=1)
df3

スクリーンショット 2021-05-23 13.51.14

'zMN'店舗の週実績の列のみを取り出します。

df = pd.DataFrame(columns=['MD週','zWM'])
df.loc[0,:]=[filepass.split("年")[0]+filepass.split("/")[1].split("週売")[0]]+list(df3.loc[:,"週実績"])
df
MD週 zWM
0 2018MD1 18820​

続けて2018年MD2週目以降、2019、2020年度の売上データも読み込んでいきます。​

import pandas as pd
import glob
targetfolder=["2018年度売上週報2", "2019年度売上週報2", "2020年度売上週報2"]
df_all = pd.DataFrame(columns=['MD週','zWM'])
counter=0
targetname=['zWM']
for folder in targetfolder:
 targetfiles=glob.glob(folder +"/*.xlsx")
 print(targetfiles)
 for filename in targetfiles:
   filepass=filename
   print(filepass)
   df= pd.read_excel(filepass)
   df = df.iloc[:,1:]
   df2=df[:10]
   try:
     df2.columns=["Unnamed: 0", "tar", "Unnamed: 2", "MD1週", "週実績",  "Unnamed: 5", "Unnamed: 6", "Unnamed: 7", "Unnamed: 8", "Unnamed: 9"]
   except:
     col = ["Unnamed: 0", "tar", "Unnamed: 2", "MD1週", "週実績",  "Unnamed: 5", "Unnamed: 6", "Unnamed: 7", "Unnamed: 8", "Unnamed: 9"]
     diff = len(df2.columns) - len(col)
     for i in range(diff):
       col.append("")
     df2.columns=col
   df2= df2.query("tar in @targetname")
   df3=df2.drop("Unnamed: 0", axis=1)
   df_all.loc[counter,:]=[filepass.split("年")[0]+filepass.split("/")[1].split("週売")[0]]+list(df3.loc[:,"週実績"])
   counter+=1

並べ替え

抜けている部分がないか確認するため、ソートで昇順に並べ替えます。

df_all.sort_values(by="MD週")

スクリーンショット 2021-05-23 13.56.12

df_all

スクリーンショット 2021-05-23 13.57.23

欠損値の確認

昇順に並べ替えをしつつ、欠損値を確認します。

import glob
targetfolder=["2018年度売上週報2", "2019年度売上週報2", "2020年度売上週報2"]
df_all = pd.DataFrame(columns=['MD週','zWM'])
counter=0
targetname=['zWM']
for folder in targetfolder:
 #targetfiles=glob.glob(folder +"/*.xlsx")
 #print(targetfiles)
 for num in range(53):
   filepass=folder+"/MD{}週売上週報.xlsx".format(num)
   try:
       df= pd.read_excel(filepass)
       df = df.iloc[:,1:]
       print(filepass)
       df2=df[:10]
       try:
         df2.columns=["Unnamed: 0", "tar", "Unnamed: 2", "MD1週", "週実績",  "Unnamed: 5", "Unnamed: 6", "Unnamed: 7", "Unnamed: 8", "Unnamed: 9"]
       except:
         col = ["Unnamed: 0", "tar", "Unnamed: 2", "MD1週", "週実績",  "Unnamed: 5", "Unnamed: 6", "Unnamed: 7", "Unnamed: 8", "Unnamed: 9"]
         diff = len(df2.columns) - len(col)
         for i in range(diff):
           col.append("")
         df2.columns=col
       df2= df2.query("tar in @targetname")
       df3=df2.drop("Unnamed: 0", axis=1)
       df_all.loc[counter,:]=[filepass.split("年")[0]+filepass.split("/")[1].split("週売")[0]]+list(df3.loc[:,"週実績"])
       counter+=1
   except:
       print("/MD{}週売上週報 はありませんでした".format(num))

スクリーンショット 2021-05-23 13.58.28

csvデータに変換します。

df_all.to_csv("tmp.csv")

欠損値の補完

csvデータを読み込みます。

import pandas as pd
df= pd.read_csv("tmp.csv", index_col=0)
df

スクリーンショット 2021-05-23 14.00.03

欠損値を補完するため、各列ごとに平均や標準偏差、最大値、最小値、最頻値などの要約統計量を取得します。

df.describe()

スクリーンショット 2021-05-23 14.29.12

今回は平均値で補完します。

mean_data=df.describe().loc["mean"]
mean_data
zWM 16789.626984
Name: mean, dtype: float64

欠損している部分に平均値を補完します。

import glob
targetfolder=["2018", "2019", "2020"]
new_df = pd.DataFrame(columns=['MD週','zWM'])
counter=0
targetname=['zWM']
for folder in targetfolder:
 #targetfiles=glob.glob(folder +"/*.xlsx")
 #print(targetfiles)
 for num in range(1, 53):
   tmp=folder+ "MD"+ str(num)
   data=df.query("MD週==@tmp")
   if len(data) == 0:
     new_df.loc[counter,:]= [tmp]+ list(mean_data)
   else:
     new_df.loc[counter,:]= data.values
   counter+=1
new_df

スクリーンショット 2021-05-23 14.03.56


list(data.values)
[array(['2020MD52', 11638], dtype=object)]

csvデータの作成

csvデータに変換します。

new_df.to_csv("/content/drive/MyDrive/new_df_zWM.csv")


【気象庁データクレンジング・成形】

気象庁のCSVデータ読み込み

続けて気象庁のCSVデータを読み込んでいきます。

import pandas as pd
df= pd.read_csv("data.csv", encoding='cp932', header=2)
df

スクリーンショット 2021-05-23 14.45.18

0行目と1行目は不要なため、削除します。

df= df.drop([0,1])
df

スクリーンショット 2021-05-23 14.48.36

今回欲しいデータ、"年月日", "降水量の合計(mm)", "最高気温(℃)", "最低気温(℃)"だけを取り出します。

target_column= ["年月日", "降水量の合計(mm)", "最高気温(℃)", "最低気温(℃)"]
for col in df.columns:
 if col in target_column:
   pass 
 else :
   df= df.drop(col, axis=1)
df    

スクリーンショット 2021-05-23 14.51.56

csvデータに変換します。

df.to_csv("wether.csv")

週毎の売り上げデータとデータ数を揃えるため、日毎の気象データを週毎のデータに変更します。

df= pd.read_csv("wether.csv", index_col=0)
df= df.reset_index(drop=True)
df= df.drop(df.index[-7:])
df

スクリーンショット 2021-05-23 14.56.42

"降水量の合計(mm)", "最高気温(℃)", "最低気温(℃)"を週毎の平均数値にします。

new_df = pd.DataFrame(columns=df.columns[1:])
counter=0
for i in range(0, len(df), 7):
 tmp= df.iloc[i : i+7, 1: ].describe()
 new_df.loc[counter,:]= tmp.loc["mean"]
 counter+=1
new_df  

スクリーンショット 2021-05-23 14.58.27

csvデータに変換します。

new_df.to_csv("wether_week.csv")


【売り上げCSVデータと気象庁CSVデータの統合】


データ読み込み

作成した、売り上げCSVデータと気象庁CSVデータを統合します。
まずは売上CSVデータを読み込んでいきます。

import pandas as pd
df_s= pd.read_csv("new_df_zWM.csv", index_col=0)
df_s

スクリーンショット 2021-05-23 15.08.15

続けて気象庁のCSVデータを読み込んでいきます。

import pandas as pd
df_w= pd.read_csv("wether_week.csv", index_col=0)
df_w

スクリーンショット 2021-05-23 15.09.01

売り上げCSVデータと気象庁CSVデータを統合します。

df= pd.concat([df_s, df_w], axis=1)
df

スクリーンショット 2021-05-23 15.10.55

csvデータの作成

csvデータに変換します。

df.to_csv("sales_wether.csv")


前回必要なデータを揃えるのに、約10時間、データの整形に約10時間かかりましたが、回数を重ねることで必要なデータの見極めがスムーズになり、2時間程度で整えることができました。
データの読み込みを始める前に、ある程度データの中身を確認し、あらかじめ整えておくことでスムーズに進められてよかったです。

「【プログラミング初心者】が売上を予測してみました(vol.4:データ整理編)」はこちらで終わりです。
続きは「vol.5 : モデル作成編 / 線形重回帰モデル・LSTMモデル」です。こちらもぜひご覧くださいませ。

もしよければ、「【プログラミング初心者】が売上を予測してみました(vol.1 : データ整理編)、(vol.2 : 時系列解析編)、(vol.3 : 回帰編)」
「【プログラミング初心者】が在庫を予測してみました 」もあわせてぜひご覧くださいませ。
最後まで読んでいただき、ありがとうございました。


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