第
5
章
数据分析与可视化
本章概要
当获得数据后,如果想从数据中挖掘出一些关键信息,就先要了解这份数据, 
即本节将要介绍的数据分析。在Python语言中,Pandas是高性能计算和数据分
析的基础包,在数据工程中已得到广泛应用。

而从数据中提取出来有吸引力的图表更是一件非常重要的事情,这就是数据
可视化的工作。数据可视化是一个非常直观的查看数据手段。Matplotlib是
Python主要的科学绘图库,其功能为生成可发布的可视化内容,如折线图、直方
图、散点图等。将数据及各种分析可视化,可以让用户产生深刻的理解。

本章将根据数据分析流程,依次介绍数据获取、数据预处理、数据分析的操作
方法,并借助Python的NumPy、Pandas、Matplotlib等模块所提供的计算、分析、
统计和绘图功能,来总体介绍实用数据分析和数据可视化方法。

学习目标

通过本章的学习,要求达到以下目标: 

(1)了解数据分析的目标。
(2)掌握Pandas数据分析模块。
(3)掌握DataFrame 数据结构的使用。
(4)掌握Matplotlib的数据可视化方法。
(5)理解Seaborn高级数据可视化手段。
..5.1 
Python数据分析

Pandas(PythonDataAnalysisLibrary)是Python的一个数据分析包,是基于
NumPy的一种工具,为了解决数据分析任务而创建。

Pandas使用强大的数据结构提供高性能的数据操作和分析工具。模块提供
了大量的能便捷处理数据的函数、方法和模型,还包括操作大型数据集的工具,从
而高效分析数据。

Pandas主要处理以下三种数据结构。


第5章 数据分析与可视化1 05 
(1)Series:一维数组,与NumPy中一维的ndarray类似。数据结构接近Python中的
List列表,数据元素可以是不同的数据类型。
(2)DataFrame:二维数据结构。DataFrame可以理解成Series的容器,其内部的每项
元素都可以看作一个Series。DataFrame是重要的数据结构,在机器学习中经常使用。
(3)Panel:三维数组,可以理解为DataFrame的容器,其内部的每项元素都可以看作
一个DataFrame。
这些数据结构都是构建在NumPy数组的基础之上,运算速度很快。
5.1.1 Series数据结构
Series是一种类似于一维数组的对象,由一组数据以及一组与之相关的数据标签(即索
引)组成,数据可以是任何NumPy数据类型(如整数、字符串、浮点数、Python对象等)。
1.创建Series对象
创建Series对象可以使用函数Series(data,index),参数data表示数据值,index是索
引,默认情况下会自动创建一个0~N -1(N 为数据的长度)的整数型索引。访问Series对
象的成员的方法类似narray数组,使用索引或索引名进行访问。
例5-1:创建一个Series对象。 
import pandas as pd 
s = pd.Series([1,3,5,9,6,8]) 
print(s) 
例5-2:为一个地理位置数据创建Series对象。 
import pandas as pd 
#使用列表创建,索引值为默认值
print('-------- 列表创建series ----------') 
s1=pd.Series([1,1,1,1,1]) 
print(s1) 
print('-------- 字典创建series ----------') 
#使用字典创建,索引值为字典的key 值
s2=pd.Series({'Longitude':39,'Latitude':116,'Temperature':23}) 
print('First value in s2:',s2['Longitude']) 
print('-------- 用序列作series 索引----------') 
#使用range()函数生成的迭代序列设置索引值
s3=pd.Series([3.4,0.8,2.1,0.3,1.5],range(5,10)) 
print('First value in s3:',s3[5]) 
2.访问Series数据对象
1)修改数据
可以通过赋值操作直接修改Series对象成员的值,还可以为多个对象成员批量修改
数据。例
5-3:对例5-2中创建的s2,将温度增加2,设置城市为“Beijing”。 
#温度增加2 度,设置城市为Beijing

1 06 数据智能———Python数据分析与可视化 
s2["City"]="Beijing" 
s2['Temperature']+=2 
s2 
运行结果如图5-1所示。
2)按条件表达式筛选数据
例5-4:找出例5-2的s3中大于2的数据。 
s3[s3>2] 
输出结果如图5-2所示。
图5-1 例5-3运行结果 图5-2 例5-4输出结果
3)增加对象成员
两个Series对象可以通过append()函数进行拼接,从而产生一个新的Series对象。进
行拼接操作时,原来的Series对象内容保持不变。
例5-5:为s2添加一项湿度数据。 
stiny=pd.Series({'humidity':84}) 
s4=s2.append(stiny) 
print('-------原Series: -------\n',s2) 
print('-------新Series: -------\n',s4) 
输出结果如图5-3所示。
图5-3 例5-5输出结果
可以看到,合并操作不影响原Series。结果中原s2数据没有变化,新创建的s4对象接
收了合并后的新数据。
4)删除对象成员
可以通过drop()函数删除对象成员,可以删除一个或多个对象成员。与append()函数

第5章 数据分析与可视化1 07 
一样,drop()函数也不改变原对象的内容,返回一个新的Series对象。
例5-6:删除重量数据。 
s2=s2.drop('City') 
s2 
输出结果如图5-4所示。
图5-4 例5-6输出结果
5.1.2 DataFrame对象
DataFrame是一个表格型的数据结构,包含一组有序数列。列索引(columns)对应表
格的字段名,行索引(index)对应表格的行号,值(values)是一个二维数组。每一列表示一个
独立的属性,各个列的数据类型(数值、字符串、布尔值等)可以不同。
DataFrame既有行索引也有列索引,所以DataFrame也可以看成是Series的容器。
1.创建DataFrame对象
构建DataFrame的办法有很多,基本方法是使用DataFrame()函数构造,格式如下。 
DataFrame([data, index, columns, dtype, copy]) 
1)从字典构建DataFrame 
例5-7:从字典数据创建DataFrame。 
import pandas as pd 
dict1 = {'col1':[1,2,5,7],'col2':['a','b','c','d']} 
df = pd.DataFrame(dict1) 
df 
运行结果如图5-5所示。
图5-5 例5-7运行结果
例5-8:由列表组成DataFrame。 
lista = [1,2,5,7] 
listb = ['a','b','c','d'] 
df = pd.DataFrame({'col1':lista,'col2':listb}) 
df

1 08 数据智能———Python数据分析与可视化
2)从数组创建DataFrame 
可以使用Python的二维数组作为数值,通过columns参数指定列名,构建DataFrame。
例5-9:二维数组和columns构建DataFrame。 
import pandas as pd 
a = pd.DataFrame([[1,0.1,5], 
[2,0.5,6], 
[4,0.8,5]],columns = ["t1", "t2", "pl"]) 
a
运行结果如图5-6所示。
也可以从NumPy提供的ndarray结构创建DataFrame。
例5-10:从二维ndarray创建DataFrame。 
a = np.array([[1,2,3], [4,5,6],[7,8,9]]) 
b=pd.DataFrame(a) 
b
运行结果如图5-7所示。
图5-6 例5-9运行结果 图5-7 例5-10运行结果
3)从csv文件中读取数据到DataFrame 
通过第4章内容我们了解到,Pandas还提供读写csv文件功能。例如,read_csv()函数
可以读取csv文件的数据,返回DataFrame对象。
2.访问DataFrame对象
从本质上来说,Series或DataFrame的索引是一个Index对象,负责管理轴标签等。在
构建Series或DataFrame时,所使用的数组或序列的标签会转换成索引对象。因此,Series 
的索引不只是数字,也包括字符等。对DataFrame进行索引,可以获取其中的一个或多个
列,列可以通过索引进行访问。
例5-11:对Series和DataFrame进行索引。 
import numpy as np 
import pandas as pd 
ser=pd.Series(np.arange(4),index=['A','B','C','D']) #构造一个Series 
data=pd.DataFrame(np.arange(16).reshape(4,4), 
index=['BJ','SH','GZ','SZ'], 
columns=['q','r','s','t']) 
print("ser['C']:",ser['C']) 
print("ser[2]:",ser[2]) 
print("data['q']:",data['q']) 
print("data[['q','t']]:",data[['q','t']])

第5章 数据分析与可视化1 09 
所构成的二维DataFrame数组data的内容如图5-8所示。
运行结果如图5-9所示。
图5-8 二维数组data 图5-9 例5-11运行结果
也可以通过切片或条件筛选进行数据过滤。
例5-12:数据切片与筛选。 
data[:2] 
data[data['s']<=10] 
运行结果如图5-10所示。
图5-10 例5-12运行结果
还可以使用loc()和iloc()函数进行切片。
其中,按索引名关键字抽取指定行列的数据使用loc()函数,标准格式如下。 
<DataFrame 对象>.loc[<行索引名或行索引名列表>,<列索引名或列索引名列表>] 
按位置访问指定行列时,可以使用iloc()函数,同样有行、列两个参数,可以是下标值, 
可以是列表,还可以是切片,标准格式如下。 
<DataFrame 对象>.iloc[<行参数>,<列参数>] 
例5-13:抽取指定行列的数据。 
data.loc[['SH','GZ'],['r','s']] 
或: 
data.iloc[:-1,1:3] 
运行结果如图5-11所示。

1 10 数据智能———Python数据分析与可视化
图5-11 例5-13运行结果
3.修改DataFrame数据
1)修改数据
通过赋值语句修改数据,可以修改指定行、列的数据,还可以把要修改的数据查询筛选
出来,或重新赋值。
例5-14:修改数组中的某个数据。 
import numpy as np 
import pandas as pd 
data=pd.DataFrame(np.arange(16).reshape(4,4), 
index=['BJ','SH','GZ','SZ'], 
columns=['q','r','s','t']) 
data['q']['BJ']=8 
data['t']=8 
data['s']['SZ']=8 
data 
运行结果如图5-12所示。
2)增加列
可以为DataFrame对象添加新的列,通过赋值语句赋值时,只要列索引名不存在,就添
加新列,否则就修改列值,这与字典的特性相似。
例5-15:为data增加一列“u”,值为9。 
data['u']=9 
data 
运行后data如图5-13所示。
图5-12 例5-14运行结果 图5-13 例5-15运行结果
3)合并添加数据
DataFrame对象可以增加新列,但与Series对象一样不能直接增加新行。如果需要增加
几行数据,需要将数据存入一个新DataFrame对象,然后将两个DataFrame对象进行合并。

第5章 数据分析与可视化1 11 
两个DataFrame对象的合并可以使用Pandas的concat()方法,通过axis参数的选择, 
能够按不同的轴向连接两个DataFrame对象。
4)删除DataFrame对象的数据
drop()函数可以按行列删除数据,drop()函数基本格式如下。 
<DataFrame 对象>.drop(索引值或索引列表,axis=0, inplace=False,…) 
主要参数如下。
● axis:默认为0,为行索引值或列索引列表;值为0表示删除行,值为1表示删除列。
● inplace:逻辑型,表示操作是否对原数据生效。默认为False,产生新对象,原
DataFrame对象内容不变。
例5-16:DataFrame对象的删除操作。 
dt1=data.drop('SZ',axis=0) #删除index 值为'SZ'的行
dt2=data.drop(["r","u"],axis=1) #删除"r","u"列
data.drop('SZ',inplace=True) #从原数据中删除一行
运行结果如图5-14所示。
图5-14 例5-16运行结果
4.汇总和描述性统计计算
Pandas的Series对象和DataFrame对象都继承了NumPy的统计函数,常用的数学和
统计方法如表5-1所示,通常可以对一列或多列数据进行统计分析。
表5-1 常用的描述和汇总统计函数
函 数 名功能说明
count 统计数据值的数量,不包括NA值
describe 对Series、DataFrame进行汇总统计
min,max 计算最小值、最大值
argmin,argmax 计算最小值、最大值的索引位置
idxmin,idxmax 计算最小值、最大值的索引值
sum 计算总和
mean 计算平均值
median 返回中位数
var 计算样本值的方差
std 计算样本值的标准差
cumsum 计算样本值的累计和
diff 计算一阶差分

1 12 数据智能———Python数据分析与可视化 
例5-17:一个简单的DataFrame。 
df=pd.DataFrame(np.arange(16).reshape(4,4), 
index=['BJ','SH','GZ','SZ'], 
columns=['q','r','s','t']) 
df 
DataFrame的跨行用0轴表示,跨列用1轴表示。例如,按0轴求和的操作如下。 
df.sum() 
或: 
df.sum(axis=0) 
运行结果如图5-15所示。
按1轴求和操作如下。 
df.sum(axis=1) 
运行结果如图5-16所示。
图5-15 按0轴求和 图5-16 按1轴求和
求平均值的操作如下。 
df.mean(axis=1) 
图5-17 求平均值
运行结果如图5-17所示。
求最大值和最小值也很方便,分别使用df.max()、df. 
min()方法。
例5-18:综合示例———英文分词。
在文本处理中,分词是一项基本任务,能够表达内容
相关性、提取页面关键词、主题标签等。下面对英文句子
进行基本的单词频率提取。 
#使用变量p 保存英文句子
p='life can be good,life can be sad,life is mostly cheerful,but sometimes sad.' 
pList=p.split() #使用split()函数进行分隔
pdict={} 
#对分隔后的词语进行统计
for item in pList: 
if item[-1]in ',.': 
item=item[:-1] 
if item not in pdict:

第5章 数据分析与可视化1 13 
pdict[item]=1 
else: 
pdict[item]+=1 
print(pdict) 
输出的分词结果如图5-18所示。
图5-18 分词结果
5.分组统计
在日常的数据分析中,经常需要将数据根据一个或多个字段划分为不同的组进行分析, 
如电商领域将全国的总销售额按省份进行分组,并分析各省销售额的变化情况;或者社交网
站将用户根据性别、年龄等特征进行细分,据此研究用户画像和偏好等。
在Pandas中,上述分组操作主要运用groupby()函数完成,然后进行基本的分组操作, 
如组内计数、求和、求均值和求方差等。
例5-19:对电影评分数据集合IMDB300进行处理,按职业进行分组,统计各职业的用
户人数。
分析:按职业进行分组,可以使用groupby('uOccup')进行分组。还通常使用groupby 
分组对象的size()方法以返回组大小(Series结构),使用count()方法进行组内特征计数
(Series或Dataframe结构)。 
import pandas as pd 
f = open('score.txt',encoding='UTF-8') 
df=pd.read_csv(f,sep='\t',header= None,names=['Index','uNo','uAge','uOccup', 
'filmNo', 'filmName','url','score','timestamp']) 
#分组统计
df.groupby('uOccup').size() #查看组大小结果
从运行结果可以看出,size()方法返回的是当前组的大小,如图5-19所示。
图5-19 返回当前组的大小
再增加下面的语句: 
df.groupby('uOccup').count() #查看计数结果
可以得到如图5-20所示结果。
从运行结果可以看到,count()方法返回的是一个DataFrame结构,内容为各组的全部
特征的计数。