import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
from IPython.display import display
%matplotlib inline

"""
Explanation: 這個筆記本的目地是探索政府公開的信用卡消費資料集：
各年齡層持卡人於十六縣消費樣態(http://data.gov.tw/node/38320)

認識並整理資料
備註：建立與解除索引
我們已經了解了如何製作食品餐飲類的資料表。現在，我們要將七大類各別做成一個資料表，然後將它們連結起來，成為一個最終資料表
畫盒鬚圖，以了解不同縣市下，各年齡層的消費狀況
畫散佈圖來了解不同縣市下，商品數量和商品價格的關係
繼續畫散佈圖，目的是了解於不同月份下，商品數和商品價格的關係
不同商品類型底下，商品數和商品價格的關係
End of explanation
"""


df=pd.DataFrame.from_csv('../datasets/BANK_LOC_ALL_AG.csv',sep=';',encoding='utf8',index_col=['年月','地區'])

df.head(3)

"""
Explanation: <a id="01"/>認識並整理資料
End of explanation
"""


colInd=[j for j in range(0,196,14)]

colInd

df.iloc[0,colInd]

def transf(x,*args):
    return x[list(args)]

"""
Explanation: 先了解一下各欄位

年齡區段：[0-20), [20,25),[25,30),....[75-80),[80-)。共$1+6\times2+1=14$個年齡區間。
類別：食品餐飲，衣著飾品，旅館住宿，交通，文教康樂，百貨，其他。共7類。
一個年齡區段和一個類別之下，含有兩筆記錄，分別是交易比數，和交易金額。
縣市共有16個。
時間為105年4月到9月，共六個月。
欄位共有$14\times7\times2+2$(某年月某地區)=198個。

由於該資料表欄位過多，因此在進行分析前，我希望先行整理此資料表。以下將進行資料表的整理。以下我們先試著先整理出食品餐飲類的資料
End of explanation
"""


s1=df.apply(transf,axis=1,args=[j for j in range(0,196,14)])
s1.columns=['0-20','20-25','25-30','30-35','35-40','40-45','45-50','50-55','55-60','60-65','65-70','70-75','75-80','80-']

"""
Explanation: 建立表s1, 存放消費筆數
End of explanation
"""


s2=df.apply(transf,axis=1,args=[j for j in range(1,196,14)])
s2.columns=['0-20','20-25','25-30','30-35','35-40','40-45','45-50','50-55','55-60','60-65','65-70','70-75','75-80','80-']

s1.index

s1.head(3)

idx=pd.MultiIndex(levels=[['食品餐飲'],['105年04月', '105年05月', '105年06月', '105年07月', '105年08月', '105年09月'], ['南投縣', '台東縣', '嘉義市', '嘉義縣', '基隆市', '宜蘭縣', '屏東縣', '彰化縣', '新竹市', '新竹縣', '澎湖縣', '花蓮縣', '苗栗縣', '連江縣', '金門縣', '雲林縣']],
           labels=[[0]*96,[0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5], [4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 12, 12, 12, 12, 12, 12, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 11, 11, 11, 11, 11, 11, 1, 1, 1, 1, 1, 1, 10, 10, 10, 10, 10, 10, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13]],
           names=['類別','年月', '地區'])

s1.index,s2.index=idx,idx

s1.head(3)

s1.shape

s1.stack().head(5)

s2.stack().head(5)

"""
Explanation: 建立表s2, 存放消費金額
End of explanation
"""


dfFoods=pd.concat([s1.stack(),s2.stack()],axis=1)

dfFoods.columns=['筆數','金額']

dfFoods.index.names=['類別', '年月', '地區', '年齡']

dfFoods.head(5)

dfFoods.index.levels

"""
Explanation: 將消費比數s1.stack()和消費金額s2.stack()兩張表結合。
End of explanation
"""


dfFoods.reset_index(level='年齡').head(3)

"""
Explanation: 食品餐飲類的資料表建立完成。

<a id="02"/>備註：建立與解除索引
使用reset_index(level='年齡')將造成'年齡'索引變成欄位。
End of explanation
"""


dfFoods.reset_index().head(3)

"""
Explanation: 使用reset_index()將造成所有索引變成欄位。
End of explanation
"""


dfFoods.reset_index().set_index(['類別', '年月', '地區', '年齡']).head(3)

"""
Explanation: 使用set_index(indexes)可將欄位變回索引。
End of explanation
"""


def transf(x,*args):
    return x[list(args)]

df=pd.DataFrame.from_csv('../datasets/BANK_LOC_ALL_AG.csv',sep=';',encoding='utf8',index_col=['年月','地區'])

types=['食品餐飲','衣著飾品','旅館住宿','交通','文教康樂','百貨','其他']

dfs=[]
for tpeIdx,tpe in enumerate(types):
    s1=df.apply(transf,axis=1,args=[j for j in range(2*tpeIdx,196,14)])
    s1.columns=['0-20','20-25','25-30','30-35','35-40','40-45','45-50','50-55','55-60','60-65','65-70','70-75','75-80','80-']
    s2=df.apply(transf,axis=1,args=[j for j in range(2*tpeIdx+1,196,14)])
    s2.columns=['0-20','20-25','25-30','30-35','35-40','40-45','45-50','50-55','55-60','60-65','65-70','70-75','75-80','80-']
    idx=pd.MultiIndex(levels=[[tpe],['2016-04', '2016-05', '2016-06', '2016-07', '2016-08', '2016-09'], ['南投縣', '台東縣', '嘉義市', '嘉義縣', '基隆市', '宜蘭縣', '屏東縣', '彰化縣', '新竹市', '新竹縣', '澎湖縣', '花蓮縣', '苗栗縣', '連江縣', '金門縣', '雲林縣']],
               labels=[[0]*96,[0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5], [4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 12, 12, 12, 12, 12, 12, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 11, 11, 11, 11, 11, 11, 1, 1, 1, 1, 1, 1, 10, 10, 10, 10, 10, 10, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13]],
               names=['type', 'date', 'place'])
    s1.index,s2.index=idx,idx
    dfNew=pd.concat([s1.stack(),s2.stack()],axis=1)
    dfNew.columns=['numer of items','total amount(NTD)']
    dfNew.index.names=['type', 'date', 'place', 'age']
    dfs.append(dfNew)

df=pd.concat(dfs,axis=0)  # 連結七大類消費的資料表成為一個最終資料表

df=df.sort_index()  # 排序索引，以加速資料查找。

"""
Explanation: <a id="03"/>我們已經了解了如何製作食品餐飲類的資料表。現在，我們要將七大類各別做成一個資料表，然後將它們連結起來，成為一個最終資料表
End of explanation
"""


df.to_csv('../datasets/BANK_LOC_ALL_AG_fixed.csv')

import tables
df.to_hdf('../datasets/BANK_LOC_ALL_AG_fixed.h5','table',complib='bzip2')

!ls -hl BANK_*

df.head(15)

df.index.names

df.index.levels

df.columns

"""
Explanation: 將最終資料表輸出：
End of explanation
"""


df_age=df.drop('numer of items',axis=1)

df_age.index.levels[1]

print(df_age.index.levels[2])
print(len(df_age.index.levels[2]))

cities=["NantouCny","TaitungCny","ChiayiCty","ChiayiCny",
        "KeelungCty","YeelanCny","PingTongCny","ChanghwaCny",
       "HsingzuCty","HsingzuCny","PenghuCny","HwalianCny","MiaoliCny",
       "LianchiangCny", "KingmenCny","YunlinCny"]

fig,axes=plt.subplots(8,2,figsize=(13,30),sharey=False)

for idx,city in enumerate(df.index.levels[2]):
    print(city)
    df_city=df_age.loc[(list(df_age.index.levels[0]),list(df_age.index.levels[1]),city)].reset_index('age')
    df_city.boxplot(by='age',ax=axes.reshape(-1)[idx])
    axes.reshape(-1)[idx].set_title(cities[idx])
fig.suptitle('')
plt.tight_layout()
plt.show()

"""
Explanation: 資料表整理完畢。

<a id="04"/>畫盒鬚圖，以了解不同縣市下，各年齡層的消費狀況
End of explanation
"""


groups=df.groupby(level=2)

xlabel='numer of items'
ylabel='total amount(NTD)'

fig, axes = plt.subplots(8,2,figsize=(10,30),sharex=True,sharey=True)
plt.subplots_adjust(hspace=0.5)
plt.subplots_adjust(wspace=0.5)
#ax.set_xlabel(xlabel)
#ax.set_ylabel(ylabel)

for idx, (name, group) in enumerate(groups):
    axes.reshape(-1)[idx].plot(group[xlabel], group[ylabel], marker='o', linestyle='', ms=7)
    #axes.reshape(-1)[idx].set_xlabel(xlabel)
    #axes.reshape(-1)[idx].set_ylabel(ylabel)
    axes.reshape(-1)[idx].set_title(cities[idx])
    
plt.tight_layout()
plt.show()

"""
Explanation: <a id="05"/>畫散佈圖來了解不同縣市下，商品數量和商品價格的關係
End of explanation
"""


df=pd.read_hdf('../datasets/BANK_LOC_ALL_AG_fixed.h5','table')

df[:3]

groups=df.groupby(level=1)

xlabel='numer of items'
ylabel='total amount(NTD)'

fig, axes = plt.subplots(2,3,figsize=(10,5),sharex=True,sharey=True)
fig.suptitle('results')
plt.subplots_adjust(hspace=0.5)
plt.subplots_adjust(wspace=0.5)
#ax.set_xlabel(xlabel)
#ax.set_ylabel(ylabel)

for idx, (name, group) in enumerate(groups):
    axes.reshape(-1)[idx].plot(group[xlabel], group[ylabel], marker='o', linestyle='', ms=7)
    #axes.reshape(-1)[idx].set_xlabel(xlabel)
    #axes.reshape(-1)[idx].set_ylabel(ylabel)
    axes.reshape(-1)[idx].set_title(name)
    
#plt.tight_layout()
plt.show()

"""
Explanation: 大城市有更多的消費筆數。猜測：每個斜率表示一種消費種類。某些小城市可能信用卡消費的種類偏少。
<a id="06"/>繼續畫散佈圖，目的是了解於不同月份下，商品數和商品價格的關係
End of explanation
"""


xlabel='numer of items'
ylabel='total amount(NTD)'

fig, ax = plt.subplots()
fig.suptitle('results')

ax.set_xlabel(xlabel)
ax.set_ylabel(ylabel)
ax.set_ylim((0,2.E8))

for idx, (name, group) in enumerate(groups):
    ax.plot(group[xlabel], group[ylabel], marker='o', linestyle='', ms=7,label=name)

plt.legend(loc='upper left')
plt.show()

"""
Explanation: 不同時間基本上不太影響消費數和消費金額間的關係。我們可把以上六張圖畫在一起
End of explanation
"""


df=pd.read_hdf('../datasets/BANK_LOC_ALL_AG_fixed.h5','table')

df.index.names

df.index.levels

idx=df.index.set_levels([['TRAFFIC', 'OTHERS', 'EDUENTERTAIN', 'HOTEL', 'GROCERIES', 'CLOTHES', 'FOODS'], ['2016-04', '2016-05', '2016-06', '2016-07', '2016-08', '2016-09'], ['南投縣', '台東縣', '嘉義市', '嘉義縣', '基隆市', '宜蘭縣', '屏東縣', '彰化縣', '新竹市', '新竹縣', '澎湖縣', '花蓮縣', '苗栗縣', '連江縣', '金門縣', '雲林縣'], ['0-20', '20-25', '25-30', '30-35', '35-40', '40-45', '45-50', '50-55', '55-60', '60-65', '65-70', '70-75', '75-80', '80-']])

df=df.set_index(idx)

list(df.index.levels)[0]

groups=df.groupby(level=0)

groups.indices

sns.set_palette(sns.color_palette("hls"))

xlabel='numer of items'
ylabel='total amount(NTD)'

fig, axes = plt.subplots(2,4,figsize=(10,5),sharey=True,sharex=True)
fig.suptitle('results')
plt.subplots_adjust(hspace=0.5)
plt.subplots_adjust(wspace=0.5)


for idx, (name, group) in enumerate(groups):
    axes.reshape(-1)[idx].plot(group[xlabel], group[ylabel], marker='o', linestyle='', ms=7)
    #axes.reshape(-1)[idx].set_xlabel(xlabel)
    #axes.reshape(-1)[idx].set_ylabel(ylabel)
    axes.reshape(-1)[idx].set_title(name)
    
plt.tight_layout()
plt.show()

"""
Explanation: 以上各種散佈圖，我們一直看到有不同斜率的存在。這可能反映了，不同的類型的商品，以信用卡消費的平均單價不同。因此我們以下想改為了解：
<a id="07"/>不同商品類型底下，商品數和商品價格的關係
End of explanation
"""


current_palette_7 = sns.color_palette("Paired", 7)
sns.set_palette(current_palette_7)

xlabel='numer of items'
ylabel='total amount(NTD)'

fig, ax = plt.subplots(figsize=(10,10))

ax.set_xlabel(xlabel)
ax.set_ylabel(ylabel)
for idx, (name, group) in enumerate(groups):
    ax.plot(group[xlabel], group[ylabel], marker='o', linestyle='', ms=7,label=name)

plt.ylim((0,2.E8))
plt.legend(loc='upper left')
plt.show()

"""
Explanation: x軸為消費筆數，y軸為消費價格，斜率大可能表示商品單價貴。教育類貌似有兩種斜率，這有可能代表，於某些城市，教育類的消費較便宜。
End of explanation
"""


