一行代碼制作數(shù)據(jù)分析交叉表,太便捷了
在前文中我們了解到Pandas模塊中的pivot_table()函數(shù)可以用來(lái)制作數(shù)據(jù)透視表。
模塊導(dǎo)入和數(shù)據(jù)讀取
那我們按照慣例,首先導(dǎo)入模塊并且來(lái)讀取所要使用到的數(shù)據(jù)集,引用的依然是之前制作數(shù)據(jù)透視表的數(shù)據(jù)集
import pandas as pd
def load_data():
return pd.read_csv('coffee_sales.csv', parse_dates=['order_date'])
那這里小編是通過(guò)自定義一個(gè)函數(shù),然后通過(guò)調(diào)用該函數(shù)來(lái)讀取數(shù)據(jù),在實(shí)際工作當(dāng)中每個(gè)人都可以根據(jù)自己的喜好來(lái)操作:
df = load_data()
df.head()
output
牛刀小試
交叉表是用于統(tǒng)計(jì)分組頻率的特殊透視表。簡(jiǎn)單來(lái)說(shuō),就是將兩個(gè)或者多個(gè)列中不重復(fù)的元素組成一個(gè)新的DataFrame,新數(shù)據(jù)的行和列交叉的部分值為其組合在原數(shù)據(jù)中的數(shù)量,我們先來(lái)看一個(gè)簡(jiǎn)單的例子,代碼如下:
pd.crosstab(index = df['region'], columns = df['product_category'])
output
在行方向上代表的是不同的地區(qū),而在列方向上代表的則是不同的咖啡種類,出來(lái)的結(jié)果表示的是不同地區(qū)不同咖啡種類的匯總數(shù)據(jù),
df[(df["region"] == "Central")&(df["product_category"] == "Tea")].shape[0]
output
336
例如我們篩選出地區(qū)是中部地區(qū)并且品種是茶飲的數(shù)據(jù),出來(lái)的結(jié)果總共有336條數(shù)據(jù),和交叉表中的結(jié)果一致。
我們可以對(duì)列名以及行索引更換名字,通過(guò)調(diào)用rownames參數(shù)以及colnames參數(shù),代碼如下:
pd.crosstab(
index = df['region'],
columns = df['product_category'],
rownames=['US Region'],
colnames=['Product Category']
)
output
除了咖啡的品類之外,我們還想要知道到底不同品種的咖啡在批發(fā)和零售之間銷量的數(shù)據(jù),就可以這么來(lái)操作:
pd.crosstab(
index = df['region'],
columns = [df['product_category'], df['market']]
)
output
或者是
pd.crosstab(
index = df['region'],
columns = [df['product_category'], df['market']],
rownames=['US Region'],
colnames=['Product Category', 'Market']
)
output
輸出的DataFrame數(shù)據(jù)集當(dāng)中的列有兩層,最上面的是咖啡的種類,然后緊接著第二層的便是不同的市場(chǎng),當(dāng)然我們也可以在行方向上添加多個(gè)層次的索引,代碼如下:
pd.crosstab(
index = [df['region'], df['market']],
columns = df['product_category']
)
output
進(jìn)階的操作
和pd.pivot_table()函數(shù)一樣,我們也可以通過(guò)調(diào)用當(dāng)中的margin參數(shù)來(lái)給整合出來(lái)的數(shù)據(jù)做一個(gè)加總,代碼如下:
pd.crosstab(index = df['region'],
columns = df['product_category'],
margins = True)
output
我們還能指定該列的列名。
pd.crosstab(
index = df['region'],
columns = df['product_category'],
margins = True,
margins_name = 'Subtotals'
)
output
另外還有參數(shù)normalize用來(lái)將所有值除以值的總和進(jìn)行歸一化。
pd.crosstab(index = df['region'],
columns = df['product_category'],
normalize = True)
output
我們從美觀的角度出發(fā),想要保留兩位小數(shù),代碼如下:
pd.crosstab(
index = df['region'],
columns = df['product_category'],
normalize = True
).style.format('{:.2%}')
output
要是和之間的margin參數(shù)相結(jié)合來(lái)使用的話,將所有的結(jié)果匯總到一起等于100%,代碼如下:
pd.crosstab(
index = df['region'],
columns = df['product_category'],
margins = True,
normalize = True
).style.format('{:.2%}')
output
進(jìn)一步衍生
最后還有values以及aggfunc兩參數(shù),其中aggfunc參數(shù)具體指的是指定聚合函數(shù),例如平均數(shù)、求和以及中位數(shù)等統(tǒng)計(jì)方法,對(duì)value參數(shù)指定的連續(xù)性變量的列進(jìn)行計(jì)算。
df.info()
output
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 4248 entries, 0 to 4247
Data columns (total 9 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 order_date 4248 non-null datetime64[ns]
1 market 4248 non-null object
2 region 4248 non-null object
3 product_category 4248 non-null object
4 product 4248 non-null object
5 cost 4248 non-null int64
6 inventory 4248 non-null int64
7 net_profit 4248 non-null int64
8 sales 4248 non-null int64
dtypes: datetime64[ns](1), int64(4), object(4)
memory usage: 298.8+ KB
當(dāng)前數(shù)據(jù)集中“market”、“region”、“product_category”、“product”四列是離散型變量,而有“cost”、“inventory”、“net_profit”、“sales”四列是連續(xù)性變量,分別代表的是成本、庫(kù)存、凈利潤(rùn)以及銷量,其中我們想針對(duì)不同地區(qū)、不同咖啡種類的成本做一個(gè)平均值,那么代碼如下:
pd.crosstab(
index = df['region'],
columns = df['product_category'],
values = df['cost'],
aggfunc = 'mean'
)
output
要是我們想要對(duì)計(jì)算出來(lái)的結(jié)果保留兩位小數(shù),代碼如下:
pd.crosstab(
index = df['region'],
columns = df['product_category'],
values = df['cost'],
aggfunc = 'mean'
).round(2)
output
當(dāng)然要是針對(duì)存在缺失值的情況,我們也可以替換成其他值來(lái)處理,代碼如下:
pd.crosstab(
index = df['region'],
columns = df['product_category'],
values = df['cost'],
aggfunc = 'mean',
).fillna(0)
output