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。在本例中可以使用starbucks.groupby(["Country"])来对星巴克按国家分组,然后使用starbucks.groupby(["Country"]).size()求得每个国家有多少星巴克。

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

可以看到数据不是很规范,城市名称既有中文又有英文,而且上海被存储为ShangHaiShanghai。对于上海的问题,我们将拼音全部改为小写即可;对于中文和拼音混用的问题,可以使用相应的python库(如库pinyin)将中文转换为拼音后作统计。
首先安装库pinyin,如果是在命令行里运行的python,直接pip install pinyin,安装成功后import pinyin即可。我是在jupyter notebook里面写的,外部pip安装的模块无法导入,所以使用下面的方法(或者使用conda命令安装):

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

posted @ 2018-08-04 21:52  ColdCode  阅读(2226)  评论(0编辑  收藏  举报
AmazingCounters.com