配色: 字号:
《Python程序设计》第8章 数据分析和可视化
2023-05-25 | 阅:  转:  |  分享 
  
口令:RAPID708第8章 数据分析和可视化了解“numpy”模块和“pandas”模块的主要功能。掌握“numpy”模块重要的运算方法。
掌握“pandas”模块重要的数据模型结构。了解数据可视化和GUI的区别。掌握“matplotlib”模块的重要绘图方法。Pyth
on数据分析使用“numpy”和“pandas”这两个科学运算模块。“numpy”模块:它是一个科学计算包,支持N维数组运算、处理
大型矩阵、成熟的广播函数库、矢量运算、线性代数、傅里叶变换、随机数生成等功能,并可与C++/Fortran语言无缝结合。 “pan
das”模块:是基于“numpy”的数据分析模块,提供了大量标准数据模型和高效操作大型数据集所需要的工具,可以说“pandas”是
使得Python能够成为高效且强大的数据分析环境的重要因素之一。基本属性#导入模块import numpy as np#将其他数据
类型转换为矩阵数组。>>> print(np.array([1,2,3,4,5,6])) #将列表转换为一维矩阵数组[1 2 3
4 5 6]>>> print(np.array((1,2,3,4,5,6))) #将元组转换为一维矩阵数组[1 2 3 4 5
6]#使用“numpy”模块的基本属性>>> arr1=np.array([1,2,3,4,5,6])>>> print(arr1
.ndim) #维度1>>> print(arr1.shape) #行数和列数 返回为元组类型(6,)>>> print(arr
1.size) #元素个数6创建矩阵数组#创建矩阵数组>>> import numpy as np>>> arr1=np.arr
ay([1.2,2,3,4,5],dtype=np.int) #类型设置为整形>>> print(arr1)[1 2 3 4 5]
>>> arr1=np.array([1.2,2,3,4,5],dtype=np.float) #类型设置为浮点型>>> prin
t(arr1)[ 1.2 2. 3. 4. 5. ]#赋初值>>> arr1=np.zeros((4,5)) >>
> print(arr1)[[ 0. 0. 0. 0. 0.] [ 0. 0. 0. 0. 0.] [ 0. 0
. 0. 0. 0.] [ 0. 0. 0. 0. 0.]]>>> arr2=np.ones((4,5))>>> p
rint(arr2)[[ 1. 1. 1. 1. 1.] [ 1. 1. 1. 1. 1.] [ 1. 1.
1. 1. 1.] [ 1. 1. 1. 1. 1.]]#修改矩阵数组的形状>>> arr3=np.arange(9)
.reshape(3,3)>>> print(arr3)[[0 1 2] [3 4 5] [6 7 8]]#创建线段型数据>>>
arr1=np.linspace(0,5,10)>>> print(arr1)[ 0. 0.55555556
1.11111111 1.66666667 2.22222222 2.77777778 3.33333333 3.888
88889 4.44444444 5. ]基本运算#矩阵运算>>> import numpy as np>>>
x=np.array([1,2,3,4])>>> y=np.arange(5,9)>>> z=x-y #矩阵减法>>> prin
t(z)[-4 -4 -4 -4]>>> z=x+y #矩阵加法>>> print(z)[ 6 8 10 12]>>> z=x
y #矩阵乘法>>> print(z)[ 5 12 21 32]>>> z=x/y #矩阵除法>>> print(z)[ 0
.2 0.33333333 0.42857143 0.5 ]>>> z=x3 #矩阵x的3次方
>>> print(z)[ 1 8 27 64]#可以使矩阵进行关系运算或者调用某些数学函数。>>> print(x<2) #
矩阵关系运算 判断矩阵中的每个元素是否小于数值2[ True False False False]>>> print(x==y)
#矩阵关系运算 判断矩阵x和矩阵y对应元素是否相等[False False False False]>>> z=np.sin(x)
#矩阵求正弦值>>> print(z)[ 0.84147098 0.90929743 0.14112001 -0.75680
25 ]#多维矩阵运算和一维矩阵运算的区别>>> import numpy as np>>> arr1=np.array([[1,
2,],[3,4]])>>> arr2=np.arange(5,9).reshape(2,2)>>> arr3=np.dot(ar
r1,arr2)>>> print(arr3)[[19 22] [43 50]]索引操作一维矩阵数组读取索引语法格式如下:矩阵数组
对象[索引号]>>> import numpy as np>>> arr1=np.arange(10)>>> print(arr1
[1]) #打印输出索引号为2的数据1>>> arr1=arr1.reshape(2,5)>>> print(arr1[1])
#打印输出第二行数据的数据[5 6 7 8 9]二维矩阵数组读取索引语法格式如下:矩阵数组对象[行索引][列索引]>>> pri
nt(arr1[0][1]) #打印输出第1行第2列数据1>>> print(arr1[0,2:]) #打印输出第1行第3列之后的
本行所有数值[2 3 4]矩阵数组合并将多个矩阵数组进行合并有两种方式,一种是上下合并,另一种是左右合并。矩阵数组的上下合并操作。
上下合并>>> import numpy as np>>> arr1=np.array([1,2,3])>>> arr2=np.a
rray([4,5,6])>>> print(np.vstack((arr1,arr2)))[[1 2 3] [4 5 6]]左右
合并类似于列表或字符串的拼接>>> import numpy as np>>> arr1=np.array([1,2,3])>>>
arr2=np.array([4,5,6])>>> print(np. hstack ((arr1,arr2)))[1 2 3
4 5 6]矩阵数组转置矩阵数组转置操作,使用语法如下:矩阵数组对象.T>>> import numpy as np>>> arr
1=np.array([[1,2,3],[4,5,6],[7,8,9]])>>> print(arr1) #打印输出未转置的矩阵
数组[[1 2 3] [4 5 6] [7 8 9]]>>> print(arr1.T) #打印输出
转置后的矩阵数组[[1 4 7] [2 5 8] [3 6 9]]矩阵数组分隔矩阵数组分隔有三种方式分别是:纵向分隔、横向分隔和不
等量分隔,下面详细讲解这三种分隔方式。>>> import numpy as np>>> arr1= np.arange(12).
reshape((3, 4))>>> print(np.split(arr1,2,axis=1)) #纵向分隔[array([[
0, 1], [4, 5], [8, 9]]), array([[ 2, 3], [ 6,
7], [10, 11]])]>>> print(np.split(arr1,3,axis=0)) #横向分隔[a
rray([[0, 1, 2, 3]]), array([[4, 5, 6, 7]]), array([[ 8, 9, 10,
11]])]>>> print(np.array_split(arr1,3,axis=1)) #不等量分隔[array([[0,
1], [4, 5], [8, 9]]), array([[ 2], [ 6],
[10]]), array([[ 3], [ 7], [11]])]pandas”模块是基于“numpy
”模块构建的,它使“numpy”为中心的应用变得更加简单,要使用“pandas”模块,需要了解它的两个主要数据结构:“Series
”和“DataFrame”。“Series”类似于字典,主要特点体现在索引在左边,值在右边。>>> import pandas a
s pd>>> import numpy as np>>> num=pd.Series([1,2,3,"Python"])>>>
print(num)0 11 22 33 Pythondtype: obje
ct“DataFrame”相当于是“Series”组成的字典,只不过既有行索引也有列索引。>>> import pandas as
pd>>> import numpy as np>>> dates = pd.date_range(''20180101'',per
iods=3)>>> df = pd.DataFrame(np.random.randn(3,3),index=dates,col
umns=[1,2,3])>>> print(df) 1 2
32018-01-01 -1.230292 -0.734419 2.5787212018-01-02 -0.561365 -1.
018703 -1.1527342018-01-03 -1.287677 -1.013893 -0.982593根据列索引输出对应
的数据>>> import pandas as pd>>> import numpy as np>>> dates = pd.da
te_range(''20180101'',periods=3)>>> df = pd.DataFrame(np.random.ran
dn(3,3),index=dates,columns=[1,2,3])>>> print(df[1]) #输出索引号为1的列的数
据2018-01-01 -0.2174242018-01-02 -0.6377682018-01-03 -0.1947
33Freq: D, Name: 1, dtype: float64指定行、列的索引>>> num = pd.DataFrame(
{''A'' : 1, ''B'' : pd.Timestamp(''20180101''),
''C'' : pd.Series(1,index=list(range(4)),dtype=''floa
t32''), ''D'' : np.array([3] 4,dtype=''int32''),
''E'' : pd.Categorical(["id1","id2","id3","id4"]
), ''F'' : ''Python''})>>> print(num) A
B C D E F0 1 2018-01-01 1.0 3 id1 Python1 1 2
018-01-01 1.0 3 id2 Python2 1 2018-01-01 1.0 3 id3 Pytho
n3 1 2018-01-01 1.0 3 id4 Python数据翻转>>> print(num.T)
0 1 2 \A
1 1 1 B 2
018-01-01 00:00:00 2018-01-01 00:00:00 2018-01-01 00:00:00 C
1 1 1
D 3 3 3
E id1 id2 id
3 F Python Python Pyt
hon 3 A 1 B 2018-01-
01 00:00:00 C 1 D 3 E
id4 F Python pandas数据筛选和赋值>>> dates
= pd.date_range(''20180101'', periods=6)>>> num = pd.DataFrame(np.
arange(24).reshape((6,4)),index=dates, columns=[''A'',''B'',''C'',''D''])
>>> print(num) A B C D2018-01-01 0 1 2
32018-01-02 4 5 6 72018-01-03 8 9 10 112018-01-04
12 13 14 152018-01-05 16 17 18 192018-01-06 20 21 22 2
3读取数据>>> print(num[''A'']) #或者使用 print(num.A)语句 列操作2018-01-01
02018-01-02 42018-01-03 82018-01-04 122018-01-05
162018-01-06 20Freq: D, Name: A, dtype: int32>>> print(num[
0:2]) #行操作 A B C D2018-01-01 0 1 2 32018-01-02
4 5 6 7筛选数据筛选数据主要有四种方式,根据行、列标签筛选、根据序列筛选、混合筛选和条件筛选。根据行、列标签筛选使用
的是“loc”属性。>>> print(num.loc[''20180101'']) #输出“20180101”这行数据A 0
B 1C 2D 3Name: 2018-01-01 00:00:00, dtype: int32>>> prin
t(num.loc[''20180102'',''B'']) #输出“20180102”行,“B”列的数据5>>> print(num.
loc[:,[''C'',''D'']]) #“:”代表所有行 C D2018-01-01 2 32
018-01-02 6 72018-01-03 10 112018-01-04 14 152018-01-05
18 192018-01-06 22 23根据序列筛选使用的是“iloc”属性。>>> print(num.iloc[0,0
]) #输出0行0列索引的数据0>>> print(num.iloc[0:3,0:3]) #输出0-2行,0-2列索引的数据
A B C2018-01-01 0 1 22018-01-02 4 5 62018-0
1-03 8 9 10>>> print(num.iloc[[0,3],0:3]) #输出0行和2行索引,0-2列索引对应
的数据 A B C2018-01-01 0 1 22018-01-04 12 13
14混合筛选是将标签筛选和序列筛选结合使用,使用的是“ix”属性。>>> print(num.ix[:2,[''B'',''C'']]
) B C2018-01-01 1 22018-01-02 5 6条件筛选可以提前设置约束条件然后
筛选数据。>>> print(num.C) #输出C列标签的原始数据2018-01-01 22018-01-02
62018-01-03 102018-01-04 142018-01-05 182018-01-06 2
2Freq: D, Name: C, dtype: int32>>> print(num.C>10) #判断C列标签大于10的数据
2018-01-01 False2018-01-02 False2018-01-03 False2018-01-
04 True2018-01-05 True2018-01-06 TrueFreq: D, Name: C
, dtype: bool赋值操作赋值通常使用的方式是:根据行、列设置、根据序列、标签设置和根据条件设置。根据行列设置。>>> n
um[''A'']="NULL" #A行数据都设置为“NULL”字符串>>> print(num) A
B C D2018-01-01 NULL 1 2 32018-01-02 NULL 5 6
72018-01-03 NULL 9 10 112018-01-04 NULL 13 14 152018-01-
05 NULL 17 18 192018-01-06 NULL 21 22 23根据序列、标签设置。>>> num
.iloc[0,0]=0 #将第0行、0列的数值赋值为0>>> num.loc[''20180102'',''A'']=4 #将
标签为“20180102”行、“A”列的数值赋值为4>>> print(num) A B C
D2018-01-01 0 1 2 32018-01-02 4 5 6 72018-0
1-03 NULL 9 10 112018-01-04 NULL 13 14 152018-01-05 NUL
L 17 18 192018-01-06 NULL 21 22 23根据条件设置。>>> num.A[num.A>1
0]=''Yes'' #在A列将所有大于10的数值赋值为字符串“Yes”>>> print(num) A
B C D2018-01-01 0 1 2 32018-01-02 4 5 6 72
018-01-03 8 9 10 112018-01-04 Yes 13 14 152018-01-05
Yes 17 18 192018-01-06 Yes 21 22 23可以将一条新的数据追加到旧矩阵数据中。>>>
num[''E'']=pd.Series([1,2,3,4,5,6],index=pd.date_range("20180101",p
eriods=6)) #添加新列E>>> print(num) A B C D E2018
-01-01 0 1 2 3 12018-01-02 4 5 6 7 22018-01-0
3 8 9 10 11 32018-01-04 Yes 13 14 15 42018-01-05 Ye
s 17 18 19 52018-01-06 Yes 21 22 23 6数据合并数据合并就是将多条数据合并成一
条矩阵据集,进行分析处理,数据合并有两方式:“concat( )”方法和“merge( )”方法。>>> import panda
s as pd>>> import numpy as np>>> num1 = pd.DataFrame(np.ones((3,4
))0, columns=[''A'',''B'',''C'',''D''])>>> num2 = pd.DataFrame(np.ones((
3,4))1, columns=[''A'',''B'',''C'',''D''])>>> num3 = pd.DataFrame(np.one
s((3,4))2, columns=[''A'',''B'',''C'',''D''])>>> res = pd.concat([num1,
num2, num3], axis=0, ignore_index=True)>>> print(res) A B
C D0 0.0 0.0 0.0 0.01 0.0 0.0 0.0 0.02 0.0 0.0 0
.0 0.03 1.0 1.0 1.0 1.04 1.0 1.0 1.0 1.05 1.0 1.0 1.0
1.06 2.0 2.0 2.0 2.07 2.0 2.0 2.0 2.08 2.0 2.0 2.0
2.0“concat( )”方法。“concat( )”方法可以使不同的数据矩阵合并后依照“column”(列标签名)来做纵向合并
,有相同的“column”上下合并在一起,其余的“column”自成列,原本没有值的位置均以NaN(空值)填充。>>> impor
t pandas as pd>>> import numpy as np>>> num1 = pd.DataFrame(np.on
es((3,4))0, columns=[''A'',''B'',''C'',''D''],index=[1,2,3])>>> num2 = p
d.DataFrame(np.ones((3,4))1, columns=[''B'',''C'',''D'',''E''],index=[2,
3,4])>>> res = pd.concat([num1, num2], axis=0, join=''outer'')>>> p
rint(res) A B C D E1 0.0 0.0 0.0 0.0 NaN2 0
.0 0.0 0.0 0.0 NaN3 0.0 0.0 0.0 0.0 NaN2 NaN 1.0 1.0
1.0 1.03 NaN 1.0 1.0 1.0 1.04 NaN 1.0 1.0 1.0 1.0参数“j
oin=''outer''”是预设值,因此没有设定任何参数时,系统默认“join=''outer''”。当参数“join=''inner''”
时,只有将相同的“column”合并,其余的自动舍弃。>>> res = pd.concat([num1, num2], axis
=0, join=''inner'')>>> print(res) B C D1 0.0 0.0 0.02
0.0 0.0 0.03 0.0 0.0 0.02 1.0 1.0 1.03 1.0 1.0 1.04
1.0 1.0 1.0“merge( )”方法用于多组有“key column”的数据,统一索引的数据。>>> import
pandas as pd>>> num1 = pd.DataFrame({''key'': [''K0'', ''K1'', ''K2'', ''K
3''], ''A'': [''A0'', ''A1'', ''A2'', ''A3''],
''B'': [''B0'', ''B1'', ''B2'', ''B3'']})>>> num
2 = pd.DataFrame({''key'': [''K0'', ''K1'', ''K2'', ''K3''],
''C'': [''C0'', ''C1'', ''C2'', ''C3''],
''D'': [''D0'', ''D1'', ''D2'', ''D3'']})>>> res = pd.merge(num1,
num2, on=''key'')>>> print(res) A B key C D0 A0 B0 K0
C0 D01 A1 B1 K1 C1 D12 A2 B2 K2 C2 D23 A3 B3 K3 C
3 D3“matplotlib”模块是Python中功能非常强大的画图工具。它可以画出美观的线图、散点图、条形图、柱状图、3D图
甚至图片动画等。#绘制一条“y=2x+1”的直线import matplotlib.pyplot as pltimport nu
mpy as npx=np.linspace(-1,1,50)y1=2x+1y2=x2plt.figure(num=3,fi
gsize=(5,5))plt.plot(x,y1)plt.plot(x,y2,color="red",linewidth=2,l
inestyle="--")#绘制曲线plt.xlim(-2,2)plt.ylim(-2,2)plt.xlabel("X")plt
.ylabel("Y")#添加坐标ax = plt.gca()ax.spines[''right''].set_color(''none
'')ax.spines[''top''].set_color(''none'')#添加图例plt.plot(x, y1, label=''l
inear line'')plt.plot(x, y2, color=''red'', linewidth=1.0, linestyle
=''--'', label=''square line'')plt.legend(loc=''upper right'')#添加注释plt.
text(-1,-1, r''$ test $'',fontdict={''size'': 16, ''color'': ''r''})plt.s
how()散点图import matplotlib.pyplot as pltimport numpy as npn = 1000
#1000个数据点X = np.random.normal(0, 1, n) #高斯分布/正态分布Y = np
.random.normal(0, 1, n)plt.scatter(X, Y, s=75, c="Y", alpha=.5)pl
t.xlim(-1.5, 1.5)plt.xticks(()) #隐藏X轴坐标plt.ylim(-1.5, 1.5)plt
.yticks(()) #隐藏X轴坐标plt.show()柱状图import matplotlib.pyplot as p
ltimport numpy as npn = 12 X = np.arange(n) #生成12条
数据,获取X的值(0-11)Y1 = (1 - X / float(n)) np.random.uniform(0.5, 1.
0, n)Y2 = (1 - X / float(n)) np.random.uniform(0.5, 1.0, n)plt.
bar(X, +Y1, facecolor=''#9999ff'', edgecolor=''white'') #设置上半轴plt
.bar(X, -Y2, facecolor=''#ff9999'', edgecolor=''white'') #设置下半轴fo
r x, y in zip(X, Y1): #注释说明 plt.text(x + 0.4, y + 0.05, ''%
.2f'' % y, ha=''center'', va=''bottom'')for x, y in zip(X, Y2): plt
.text(x + 0.4, -y - 0.05, ''%.2f'' % y, ha=''center'', va=''top'')plt.x
lim(-.5, n)plt.xticks(())plt.ylim(-1.25, 1.25)plt.yticks(())plt.s
how()等高线图import matplotlib.pyplot as pltimport numpy as npdef f(x
,y): return (1 - x / 2 + x6 + y3) np.exp(-x2 -y2)#25
6个数据集点n = 256x = np.linspace(-3, 3, n)y = np.linspace(-3, 3, n)#将
每一个x和每一个y分别对应起来,编织成栅格X,Y = np.meshgrid(x, y)#色彩填充plt.contourf(X,
Y, f(X, Y), 8, alpha=.75, cmap=plt.cm.hot)#绘制等高线C = plt.contour(X
, Y, f(X, Y), 8, colors=''black'', linewidth=.5)#显示等高线的数值plt.clabel
(C, inline=True, fontsize=10)plt.xticks(())plt.yticks(())plt.show
()3D绘图import numpy as npimport matplotlib.pyplot as pltfrom mpl_t
oolkits.mplot3d import Axes3Dfig = plt.figure()#将坐标轴设置为3D效果ax = A
xes3D(fig)X = np.arange(-4, 4, 0.25)Y = np.arange(-4, 4, 0.25)#将x
和y对应 设置为平面网格X, Y = np.meshgrid(X, Y)R = np.sqrt(X 2 + Y 2)#
设置高度Z = np.cos(R)#设置3D图形的跨度和颜色ax.plot_surface(X, Y, Z, rstride=1,
cstride=1, cmap=plt.get_cmap(''rainbow''))#设置投影方式ax.contourf(X, Y,
Z, zdir=''z'', offset=-2, cmap=plt.get_cmap(''rainbow''))#设置高度的范围ax.
set_zlim(-2,2)plt.show()多图合并大小相同多图合并import matplotlib.pyplot as p
ltplt.figure(figsize=(6, 4))plt.subplot(2, 2, 1)plt.plot([0, 1],
[0, 1])plt.subplot(2,2,2)plt.plot([0, 1], [0, 2])plt.subplot(2,2,
3)plt.plot([0, 1], [0, 3])plt.subplot(2,2,4)plt.plot([0, 1], [0,
4])plt.tight_layout()plt.show()大小不同多图合并import matplotlib.pyplot a
s pltplt.figure(figsize=(6, 4))plt.subplot(2, 1, 1)plt.plot([0, 1
], [0, 1])plt.subplot(2,3,4)plt.plot([0, 1], [0, 2])plt.subplot(2
,3,5)plt.plot([0, 1], [0, 3])plt.subplot(2,3,6)plt.plot([0, 1], [
0, 4])plt.show()图中图import matplotlib.pyplot as pltfig = plt.figure()x = [1, 2, 3, 4, 5, 6, 7]y = [1, 3, 4, 5, 6, 7, 8]ax1 = fig.add_axes([0.1, 0.1, 0.8, 0.8]) #绘制第一张图ax1.plot(x, y, ''r'')ax1.set_xlabel(''x'')ax1.set_ylabel(''y'')ax1.set_title(''Im1'')ax2 = fig.add_axes([0.2, 0.6, 0.25, 0.25]) #绘制第二张图ax2.plot(y, x, ''b'')ax2.set_xlabel(''x'')ax2.set_ylabel(''y'')ax2.set_title(''Im2'')plt.axes([0.6, 0.2, 0.25, 0.25]) #绘制第三张图plt.plot(y[::-1], x, ''g'') #倒序输出plt.xlabel(''x'')plt.ylabel(''y'')plt.title(''Im3'')plt.show()动态绘图import numpy as npfrom matplotlib import pyplot as pltfrom matplotlib import animationfig, ax = plt.subplots()x = np.arange(0, 2np.pi, 0.01)line, = ax.plot(x, np.sin(x))def animate(i): #动态绘制函数 line.set_ydata(np.sin(x + i/10.0)) return line,def init(): #初始化函数 line.set_ydata(np.sin(x)) return line,ani=animation.FuncAnimation(fig=fig,func=animate, frames=100, init_func=init, interval=20, blit=False)plt.show()谢谢!
献花(0)
+1
(本文系大高老师首藏)