実践データ分析　ノック11~20

**クレイジングをする方法を学ぶ**
#ノック11:データの読み込み
```ノック11.py
import pandas as pd
uriage_data=pd.read_csv("uriage.csv")
kokyaku_data=pd.read_excel("kokyaku_daicho.xlsx")
```
**uriage_data**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475270/ec4e4cab-e9fd-4a83-cd75-cf52a5887c55.png)

**kokyaku_data**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475270/f967e9fc-44f7-3922-d83b-190fcf8153fe.png)

#ノック12:データの揺れ
```ノック12.py
uriage_data["item_name"].head()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475270/735cfe3f-ba1c-c472-c2f8-f5907ed1e24c.png)

```ノック12.py
uriage_data["item_price"].head()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475270/26cc2bea-c257-5716-e945-c204bdb7e8b8.png)

#ノック13:データ揺れがあるまま集計すると...
```ノック13.py
uriage_data["purchase_date"]=pd.to_datetime(uriage_data["purchase_date"])
uriage_data["purchase_month"]=uriage_data["purchase_date"].dt.strftime("%Y%m")
res=uriage_data.pivot_table(index="purchase_month",columns="item_name",aggfunc="size",fill_value=0)
res
```
***fill_value(欠損値を何で埋めるか？)***

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475270/a027a769-a2b8-8e87-5804-10a39c69f5c7.png)

```ノック13.py
res=uriage_data.pivot_table(index="purchase_month",columns="item_name",values="item_price",aggfunc="sum",fill_value=0)
res
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475270/6aa37ba2-8a9c-f32e-e058-f1fa98d3b65e.png)

***本来26個の商品が99商品に増えてることがわかる！***

#ノック14:商品名の揺れを補正
```ノック14.py
print(len(pd.unique(uriage_data.item_name)))#再確認
>>>99
```

```ノック14.py
uriage_data["item_name"]=uriage_data["item_name"].str.upper()#小文字を大文字へ
uriage_data["item_name"]=uriage_data["item_name"].str.replace(" ","")#半角スペースを除去
uriage_data["item_name"]=uriage_data["item_name"].str.replace("　","")#全角スペースを除去
uriage_data.sort_values(by=["item_name"],ascending=True)#item_name順にソートする
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475270/4c52a80e-c830-cbdc-0e21-86bbd9debee2.png)

#ノック15:金額欠損値の補完
```ノック15.py
uriage_data.isnull().any(axis=0)#item_priceに欠損値があることが分かる
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475270/48962106-b964-d87b-2f20-a2bd920d01ce.png)

```ノック15.py
flg_is_null=uriage_data["item_price"].isnull()#item_priceの中で欠損値がある行を保存
for trg in list(uriage_data.loc[flg_is_null,"item_name"].unique()):#flg_is_nullの中でitem_nameを（商品名の重複を無くして）ループさせる
  price=uriage_data.loc[(~flg_is_null) & (uriage_data["item_name"]==trg),"item_price"].max()#~flg_is_nullはflg_is_null==Flase
  uriage_data["item_price"].loc[(flg_is_null) & (uriage_data["item_name"]==trg)]=price#item_price列に対して.locを行い、欠損を起こしている対象データを抽出して先ほど生成したpriceを欠損値に代入する
uriage_data.head()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475270/935b4a94-4d25-2c8c-7c76-c77606e6fc9a.png)

```ノック15.py
for trg in list(uriage_data["item_name"].sort_values().unique()):
  print(trg+"の最大額:"+str(uriage_data.loc[uriage_data["item_name"]==trg]["item_price"].max())+"の最小額:"+str(uriage_data.loc[uriage_data["item_name"]==trg]["item_price"].min(skipna=False)))#.min(skipna=False)はNaNデータを無視するかを設定する
```

#ノック16:顧客名の揺れを補正
```ノック16.py
kokyaku_data["顧客名"].head()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475270/53f38b2d-511f-2f5f-bb5d-fc0683035da6.png)

```ノック16.py
kokyaku_data["顧客名"]=kokyaku_data["顧客名"].str.replace("　","")
kokyaku_data["顧客名"]=kokyaku_data["顧客名"].str.replace(" ","")
kokyaku_data["顧客名"].head()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475270/fec97955-32ec-72d7-dd32-6c43942f9802.png)

#ノック17:日付の揺れを補正
```ノック17.py
flg_is_serial=kokyaku_data["登録日"].astype("str").str.isdigit()
flg_is_serial.sum()
>>>22#22件数値型として取り込まれている
```
**astype()**はデータ型を変更する
**str.isdigit()**は顧客台帳の登録日が数値かどうかを判定する

```ノック17.py
#to_timedelta関数を使ってシリアル値を日付型に変換する。
fromSerial=pd.to_timedelta(kokyaku_data.loc[flg_is_serial,"登録日"].astype("float"),unit="D")+pd.to_datetime("1900/01/01")
fromSerial
```
**詳細は以下**
https://chusotsu-program.com/pandas-to-timedelta/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475270/5c06b8a7-0d12-9e19-2487-6ab930712584.png)

```ノック17.py
#日付として取り込まれているデータも、書式統一のために処理
fromString=pd.to_datetime(kokyaku_data.loc[~flg_is_serial,"登録日"])
fromString
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475270/9d4fdb0e-da90-600c-5be1-95cc0935d324.png)

```ノック17.py
#データを合体
kokyaku_data["登録日"]=pd.concat([fromSerial,fromString])
kokyaku_data
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475270/8d0aa786-dd17-f66b-929e-0b96d6f5fc85.png)

```ノック17.py
#登録年月別に顧客数を集計する
kokyaku_data["登録年月"]=kokyaku_data["登録日"].dt.strftime("%Y%m")
rslt=kokyaku_data.groupby("登録年月").count()["顧客名"]
print(rslt)
print(len(kokyaku_data))
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475270/03b203bb-cfad-e0cf-1db8-b11ee3af0c0e.png)

```ノック17.py
#データ型統一確認
flg_is_serial=kokyaku_data["登録日"].astype("str").str.isdigit()
flg_is_serial.sum()
>>>0#数値型は0件だと確認できた
```

#ノック18:顧客名をキーに2つのデータを結合
```ノック18.py
#ノック18
join_data=pd.merge(uriage_data,kokyaku_data,left_on="customer_name",right_on="顧客名",how="left")
join_data=join_data.drop("customer_name",axis=1)
join_data
```
**left_on**はuriage_dataに含まれるキーをジョイントキーとする
**right_on**はkokyaku_dataに含まれるキーをジョイントキーとする
**join_data.drop("customer_name",axis=1)**はcustomer_name列を削除する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475270/9bcb4963-ad7f-752f-9c15-92de2e849d80.png)

#ノック19:クレイジングしたデータをダンプする
```ノック19.py
#列の順番を変えて見やすくする
dump_data=join_data[["purchase_date","purchase_month","item_name","item_price","顧客名","かな","地域","メールアドレス","登録日"]]
dump_data
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475270/b2dd8800-56d7-420f-e073-fb557bf4eaa7.png)

```ノック19.py
#dump_data.csvを出力させる
dump_data.to_csv("dump_data.csv",index=False)
```

#ノック20:データを集計する
```ノック20.py
byItem=import_data.pivot_table(index="purchase_month",columns="item_name",aggfunc="size",fill_value=0)
byItem
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475270/461d9a45-0cc9-0b27-0514-58045c541074.png)

```ノック20.py
byPrice=import_data.pivot_table(index="purchase_month",columns="item_name",values="item_price",aggfunc="sum",fill_value=0)
byPrice
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475270/38b55111-8199-a839-5c2d-31b2b1b3658f.png)


```ノック20.py
byRegion=import_data.pivot_table(index="purchase_month",columns="地域",aggfunc="size",fill_value=0)
byRegion
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475270/db155d3f-d19a-42af-38b0-87fbae419080.png)

```ノック20.py
#集計期間で購入していないユーザをチェック
away_data=pd.merge(uriage_data,kokyaku_data,left_on="customer_name",right_on="顧客名",how="right")
away_data[away_data["purchase_date"].isnull()][["顧客名","メールアドレス","登録日"]]
```
**away_data["purchase_date"].isnull()**は欠損値があるとTrue

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475270/78058337-8e6a-0b0c-5e0e-ccc545b25099.png)