pandas實戰——對星巴克數據的分析
一、實驗對象
實驗對象為星巴克在全球的門店數據,我們可以使用pandas對其進行簡單的分析,如分析每個國家星巴克的數量,根據門店數量對國家進行排序等。
二、數據分析
1、讀取數據並獲取數據行列數
首先讀取數據:
import numpy as np import pandas as pd starbucks = pd.read_csv("D:\\directory.csv") print "數據的列標簽如下:" print starbucks.columns print "每列的數據類型:" print starbucks.dtypes print "文件行數:" print len(starbucks.index) print "文件列數:" print starbucks.columns.size
輸出:
數據的列標簽如下: Index([u'Brand', u'Store Number', u'Store Name', u'Ownership Type', u'Street Address', u'City', u'State/Province', u'Country', u'Postcode', u'Phone Number', u'Timezone', u'Longitude', u'Latitude'], dtype='object') 每列的數據類型: Brand object Store Number object Store Name object Ownership Type object Street Address object City object State/Province object Country object Postcode object Phone Number object Timezone object Longitude float64 Latitude float64 dtype: object 文件行數: 25600 文件列數: 13
可以看到文件共有25600條數據,每條數據有13列。
2、查看數據
#查看文件的前五行數據
print starbucks.head()
輸出:
可以通過DataFrame.head(n)來獲取數據幀的前n行數據,未指定n則返回前5行,同樣的函數還有DataFrame.tail(n)。上圖中有些數據為NaN,如果NaN對數據處理有影響的話可以使用DataFrame.fillna(value)將NaN替換成value,或者使用DataFrame.dropna()刪除含有NaN的行。本文將不對NaN做處理。
3、按照星巴克數量由多到少對國家排序
要實現這個功能需要用到DataFrame.groupby()函數,相當於sql中的group by
df = starbucks.groupby(["Country"]).size().reset_index()
輸出:
Country
AD 1
AE 144
AR 108
AT 18
AU 22
AW 3
AZ 4
BE 19
BG 5
BH 21
BN 5
BO 4
BR 102
BS 10
CA 1468
CH 61
CL 96
CN 2734
CO 11
CR 11
CW 3
CY 10
CZ 28
DE 160
DK 21
EG 31
ES 101
FI 8
FR 132
GB 901
...
LU 2
MA 9
MC 2
MX 579
MY 234
NL 59
NO 17
NZ 24
OM 12
PA 5
PE 89
PH 298
PL 53
PR 24
PT 11
QA 18
RO 27
RU 109
SA 102
SE 18
SG 130
SK 3
SV 11
TH 289
TR 326
TT 3
TW 394
US 13608
VN 25
ZA 3
Length: 73, dtype: int64
然後我們將上一步的結果使用reset_index()方法封裝成一個新的DataFrame,然後對這個DataFrame排序即可。
#根據每個國家的國家名和星巴克數量重建為一個DataFrame
df = starbucks.groupby(["Country"]).size().reset_index()
#查看df的前5行數據
print df.head()
#修改列名(將“0”改為“Nums”)
df.columns=["Country", "Nums"]
#按照星巴克數量由多到少對國家排序
df.sort_values(by=["Nums"], ascending=False).head()
輸出:
Country 0
0 AD 1
1 AE 144
2 AR 108
3 AT 18
4 AU 22
Country Nums
70 US 13608
17 CN 2734
14 CA 1468
37 JP 1237
39 KR 993
可以看到,美國的星巴克最多,有13608家,其次是中國、加拿大、日本、韓國。由於篇幅限制只顯示了排序後的5行,可以去掉head()顯示全部數據。
4、按星巴克數量多少對中國城市排序
首先要在所有國家的數據中選擇中國的數據,可以使用布爾索引實現這一目的:
#選擇中國的數據
df = starbucks[starbucks["Country"]=="CN"]
#統計每個城市的星巴克數量
df.groupby(["City"]).size()
輸出:
City
Admiralty 2
Causeway Bay 5
Central 1
Chaiwan 1
Changshu 1
Changzhou 1
Fortress Hill 1
Hangzhou 2
Hong Kong 104
Jiaxing 2
Jinhua 1
Kowloon 19
Kowloon Bay 1
Kowloon Tong 1
Lantau Island 2
Macau 13
Mong Kok 2
N.T. 2
Nanjing 1
Nantong 4
New Territories 7
Ningbo 3
Quarry Bay 3
ShangHai 2
Shanghai 2
Shantin 1
Stanley 1
Suzhou 3
Tai Koo Shing 1
Tin Hau 1
...
蕭山市 1
蚌埠市 1
衡陽市 3
衢州市 3
襄樊市 1
襄陽市 2
西寧市 3
西安市 40
諸暨市 2
貴陽 8
貴陽市 1
連雲港 1
連雲港市 3
邢臺市 1
邯鄲 1
鄭州市 18
重慶市 41
金華市 11
銀川市 2
鎮江市 9
長春市 10
長沙市 26
陽江市 1
青島市 28
靖江市 2
鞍山市 3
馬鞍山 3
高郵市 1
黃石市 1
龍巖市 2
Length: 197, dtype: int64
可以看到數據不是很規範,城市名稱既有中文又有英文,而且上海被存儲為ShangHai
和Shanghai
。對於上海的問題,我們將拼音全部改為小寫即可;對於中文和拼音混用的問題,可以使用相應的python庫(如庫pinyin
)將中文轉換為拼音後作統計。
首先安裝庫pinyin,如果是在命令行裏運行的python,直接pip install pinyin
,安裝成功後import pinyin
即可。我是在jupyter notebook裏面寫的,外部pip安裝的模塊無法導入,所以使用下面的方法:
import pip
pip.main(['install', 'pinyin'])
安裝後導入並做相應的處理:
import pinyin
#選擇中國的數據
df = starbucks[starbucks["Country"]=="CN"]
#需要拷貝一下,不然會出現“A value is trying to be set on a copy of a slice from a DataFrame.”的警告
df1 = df.copy()
#將城市名改為小寫
df1["City"] = df1["City"].apply(lambda x:x.lower())
df2 = df1.copy()
#將漢字城市名改為小寫拼音
df2["City"] = df2["City"].apply(lambda x:pinyin.get(x, format="strip", delimiter="")[0:-3]) #去掉“市”的拼音
#統計每個城市的星巴克數量
df2.groupby(["City"]).size()
輸出:
City
admira 2
anshan 3
bangbu 1
baoding 3
baoji 1
baotou 4
beihai 1
beijing 234
causeway 5
cent 1
chai 1
chang 1
changchun 10
changsha 26
changshu 6
changz 1
changzhou 26
chengde 1
chengdu 98
cixi 5
dali 1
dalian 25
danzhou 1
daqing 2
deyang 2
dezhou 2
dongguan 31
dongyang 1
dongying 1
fenghua 2
...
yancheng 6
yangjiang 1
yangzhong 1
yangzhou 12
yanji 1
yantai 8
yichang 4
yinchuan 2
yingkou 2
yiwu 2
yixing 3
yuen l 2
yueyang 2
yuyao 1
zhangjia 1
zhangjiag 1
zhangjiagang 1
zhangzhou 1
zhanjiang 4
zhaoqing 1
zhengzhou 18
zhenjiang 9
zhongqing 41
zhongshan 11
zhous 1
zhoushan 5
zhuhai 14
zhuji 2
zhuzhou 2
zibo 5
Length: 192, dtype: int64
這裏使用到了DataFrame.apply(func)方法,該方法將函數func應用到整個DataFrame上,也可以通過指定axis參數來指定每一行或每一列的數據應用函數func。
接下來使用reset_index方法將上一步得到的數據封裝到一個新的DataFrame中排序即可。
df3 = df2.groupby(["City"]).size().reset_index()
#更改列索引名稱
df3.columns = ["City", "Nums"]
print df3.sort_values(by=["Nums"], ascending=False).head()
輸出:
City Nums
121 shanghai 542
7 beijing 234
46 hangzhou 117
126 shenzhen 113
36 guangzhou 106
可以看到在中國,上海的星巴克最多,有542家,其次的是北京、杭州、深圳和廣州,去掉.head()
可以查看所有城市的數據。
三、總結
本文主要按照星巴克數量對國家和中國的城市進行排序,用到的知識有:
- 使用DataFrame.groupby()方法對DataFrame按照一列或多列分組;
- 使用布爾索引選擇數據;
- 使用DataFrame.reset_index()方法重新指定索引(也就是把原DataFrame的行索引也當做數據並重新指定索引),該方法返回一個新的DataFrame;
- 通過對DataFrame.columns的賦值,重新指定列標簽;
- 使用DataFrame.apply(func)方法,將函數func應用到整個DataFrame上,也可以通過指定axis參數來指定每一行或每一列的數據應用函數func。
- 使用DataFrame.sort()方法對DataFrame按照某一列或者某幾列進行排序。
我們也可以看到一些pandas的操作可以與SQL操作練習起來:
1、Where語句
在上文中我們使用布爾索引選擇了中國的數據df = starbucks[starbucks["Country"]=="CN"]
,這一點很像SQL裏面的where語句select * from starbucks where Country="CN"
。
2、Select語句
starbucks有很多列,如Country,City,Brand,Postcode等,如果我們要從所有列中選擇兩列Country和City,則pandas可以使用df = starbucks[["Country", "City"]]
,與之對應的是SQL中的select語句select Country, City from starbucks
;
3、Group by語句
上文中通過國家分組,pandas使用DataFrame.groupby()方法starbucks.groupby(["Country"])
,對應的為SQL中的select * from starbucks group by Country
。
pandas實戰——對星巴克數據的分析