python数据分析库
python数据分析三大库:numpy, matplotlib, pandas
NumPy数值计算基础
掌握 NumPy 数组对象 ndarray
创建数组对象
- 数组属性:ndarray(数组)是存储单一数据类型的多维数组。
属性 | 说明 |
---|---|
ndim | 返回 int。表示数组的维数 |
shape | 返回 tuple。表示数组的尺寸,对于 n 行 m 列的矩阵,形状为(n,m) |
size | 返回 int。表示数组的元素总数,等于数组形状的乘积 |
dtype | 返回 data-type。描述数组中元素的类型 |
itemsize | 返回 int。表示数组的每个元素的大小(以字节为单位) |
- 数组创建
numpy.array(object, dtype=None, copy=True, order=‘K’,subok=False, ndmin=0)
参数名称 | 说明 |
---|---|
object | 接收array。表示想要创建的数组。无默认。 |
dtype | 接收data-type。表示数组所需的数据类型。如果未给定,则选择保存对象所需的最小类型。默认为None。 |
ndmin | 接收int。指定生成数组应该具有的最小维数。默认为None。 |
- 创建数组并查看数组属性
In[1]:
import numpy as np #导入NumPy库
arr1 = np.array([1, 2, 3, 4]) #创建一维数组
print('创建的数组为:',arr1)
Out[1]:
创建的数组为: [1 2 3 4]
In[2]:
arr2 = np.array([[1, 2, 3, 4],[4, 5, 6, 7], [7, 8, 9, 10]]) #创建二维数组
print('创建的数组为:\n',arr2)
Out[2]:
创建的数组为:
[[ 1 2 3 4]
[ 4 5 6 7]
[ 7 8 9 10]]
In[3]:
print('数组维度为:',arr2.shape) #查看数组结构
print('数组类型为:',arr2.dtype) #查看数组类型
print('数组元素个数为:',arr2.size) #查看数组元素个数
print('数组每个元素大小为:',arr2.itemsize) #查看数组每个元素大小
Out[3]:
数组维度为: (3, 4)
数组维度为: int32
数组元素个数为: 12
数组每个元素大小为: 4
- 重新设置数组的 shape 属性
In[4]:
arr2.shape = 4,3 #重新设置 shape
print('重新设置 shape 后的 arr2 为:',arr2)
Out[4]:
重新设置shape维度后的arr2为: [[ 1 2 3]
[ 4 4 5]
[ 6 7 7]
[ 8 9 10]]
- 使用 arange 函数创建数组
In[5]:
print('使用 arange 函数创建的数组为:\n',np.arange(0,1,0.1))
Out[5]:
使用arange函数创建的数组为: [ 0. 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9]
- 使用 linspace 函数创建数组
Int[6]:
print('使用 linspace 函数创建的数组为:',np.linspace(0, 1, 12))
Out[6]:
使用linspace函数创建的数组为: [ 0. 0.09090909 … 1. ]
- 使用 logspace 函数创建等比数列
Int[7]:
print('使用logspace函数创建的数组为:',np.logspace(0, 2, 20))
Out[7]:
使用logspace函数创建的数组为: [ 1. 1.27427499 1.62377674 ..., 61.58482111 78.47599704 100. ]
- 使用zeros函数创建数组
Int[8]:
print('使用zeros函数创建的数组为:',np.zeros((2,3)))
Out[8]:
使用zeros函数创建的数组为:
[[ 0. 0. 0.]
[ 0. 0. 0.]]
- 使用eye函数创建数组
Int[9]:
print('使用eye函数创建的数组为:',np.eye(3))
Out[9]:
使用eye函数创建的数组为:
[[ 1. 0. 0.]
[ 0. 1. 0.]
[ 0. 0. 1.]]
- 使用diag函数创建数组
Int[10]:
print('使用diag函数创建的数组为:',np.diag([1,2,3,4]))
Out[10]:
使用diag函数创建的数组为:
[[1 0 0 0]
[0 2 0 0]
[0 0 3 0]
[0 0 0 4]]
- 使用ones函数创建数组
Int[11]:
print('使用ones函数创建的数组为:',np.ones((5,3)))
Out[11]:
使用ones函数创建的数组为:
[[ 1. 1. 1.]
[ 1. 1. 1.]
[ 1. 1. 1.]
[ 1. 1. 1.]
[ 1. 1. 1.]]
- 数组数据类型
NumPy基本数据类型与其取值范围(只展示一部分)
类型 | 描述 |
---|---|
bool | 用一位存储的布尔类型(值为TRUE或FALSE) |
inti | 由所在平台决定其精度的整数(一般为int32或int64) |
int8 | 整数,范围为−128至127 |
int16 | 整数,范围为−32768至32767 |
int32 | 整数,范围为-231至232-1 |
… | … |
- 数组数据类型转换
Int[12]:
print('转换结果为:',np.float64(42)) #整型转换为浮点型
print('转换结果为:',np.int8(42.0)) #浮点型转换为整型
print('转换结果为:',np.bool(42)) #整型转换为布尔型
print('转换结果为:',np.bool(0)) #整型转换为布尔型
print('转换结果为:',np.float(True)) #布尔型转换为浮点型
print('转换结果为:',np.float(False)) #布尔型转换为浮点型
Out[12]:
转换结果为: 42.0
转换结果为: 42
转换结果为: True
转换结果为: False
转换结果为: 1.0
转换结果为: 0.0
创建一个存储餐饮企业库存信息的数据类型。其中,用一个长度为40个字符的字符串来记录商品的名称,用一个64位的整数来记录商品的库存数量,最后用一个64位的单精度浮点数来记录商品的价格,具体步骤如下。
- 创建数据类型
Int[13]:
df = np.dtype([("name", np.str_, 40), ("numitems", np.int64), ("price",np.float64)])
print('数据类型为:',df)
Out[13]:
数据类型为: [('name', '<U40'), ('numitems', '<i8'), ('price', '<f8')]
2)查看数据类型,可以直接查看或者使用numpy.dtype函数查看。
Int[14]:
print('数据类型为:',df["name"])
print('数据类型为:',np.dtype(df["name"]))
Out[14]:
数据类型为: <U40
数据类型为: <U40
在使用array函数创建数组时,数组的数据类型默认是浮点型。自定义数组数据,则可以预先指定数据类型
Int[15]:
itemz = np.array([("tomatoes", 42, 4.14), ("cabbages", 13, 1.72)], dtype=df)
print('自定义数据为:',itemz)
Out[15]:
自定义数据为: [('tomatoes', 42, 4.14) ('cabbages', 13, 1.72)]
生成随机数
- 无约束条件下生成随机数
Int[16]:
print('生成的随机数组为:',np.random.random(100))
Out[16]:
生成的随机数组为: [ 0.15343184 0.51581585
0.07228451 ... 0.24418316
0.92510545 0.57507965]
- 生成服从均匀分布的随机数
Int[17]:
print('生成的随机数组为:\n',np.random.rand(10,5))
Out[17]:
生成的随机数组为:
[[ 0.39830491 0.94011394 0.59974923 0.44453894 0.65451838]
...
[ 0.1468544 0.82972989 0.58011115 0.45157667 0.32422895]]
- 生成服从正态分布的随机数
Int[18]:
print('生成的随机数组为:\n',np.random.randn(10,5))
Out[18]:
生成的随机数组为:
[[-0.60571968 0.39034908 -1.63315513 0.02783885 -1.84139301]
...,
[-0.27500487 1.41711262 0.6635967 0.35486644 -0.26700703]]
- 生成给定上下范围的随机数,如创建一个最小值不低于 2、最大值不高于 10 的 2 行 5 列数组
Int[19]:
print('生成的随机数组为:',np.random.randint(2,10,size = [2,5]))
Out[19]:
生成的随机数组为: [[6 6 6 6 8]
[9 6 6 8 4]]
- random模块常用随机数生成函数
函数 | 说明 |
---|---|
seed | 确定随机数生成器的种子。 |
permutation | 返回一个序列的随机排列或返回一个随机排列的范围。 |
shuffle | 对一个序列进行随机排序。 |
binomial | 产生二项分布的随机数。 |
normal | 产生正态(高斯)分布的随机数。 |
beta | 产生beta分布的随机数。 |
chisquare | 产生卡方分布的随机数。 |
gamma | 产生gamma分布的随机数。 |
uniform | 产生在[0,1)中均匀分布的随机数。 |
通过索引访问数组
- 一维数组的索引
Int[20]:
arr = np.arange(10)
print('索引结果为:',arr[5]) #用整数作为下标可以获取数组中的某个元素
print('索引结果为:',arr[3:5]) #用范围作为下标获取数组的一个切片,包括arr[3]不包括arr[5]
print('索引结果为:',arr[:5]) #省略开始下标,表示从arr[0]开始
print('索引结果为:',arr[-1]) #下标可以使用负数,-1表示从数组后往前数的第一个元素
arr[2:4] = 100,101
print('索引结果为:',arr) #下标还可以用来修改元素的值
#范围中的第三个参数表示步长,2表示隔一个元素取一个元素
print('索引结果为:',arr[1:-1:2])
print('索引结果为:',arr[5:1:-2]) #步长为负数时,开始下标必须大于结束下标
Out[20]:
索引结果为: 5
索引结果为: [3 4]
索引结果为: [0 1 2 3 4]
索引结果为: 9
索引结果为: [ 0 1 100 101 4 5 6 7 8 9]
索引结果为: [ 1 101 5 7]
索引结果为: [ 5 101]
- 多维数组的索引
Int[21]:
arr = np.array([[1, 2, 3, 4, 5],[4, 5, 6, 7, 8], [7, 8, 9, 10, 11]])
print('创建的二维数组为:',arr)
print('索引结果为:',arr[0,3:5]) #索引第0行中第3和4列的元素
#索引第2和3行中第3~5列的元素
print('索引结果为:',arr[1:,2:])
print('索引结果为:',arr[:,2]) #索引第2列的元素
Out[21]:
创建的二维数组为: [[ 1 2 3 4 5]
[ 4 5 6 7 8]
[ 7 8 9 10 11]]
索引结果为: [4 5]
索引结果为: [[ 6 7 8]
[ 9 10 11]]
索引结果为: [3 6 9]
- 多维数组的索引(使用整数和布尔值索引访问数据)
Int[22]:
#从两个序列的对应位置取出两个整数来组成下标:arr[0,1], arr[1,2], arr[2,3]
print('索引结果为:',arr[(0,1,2),(1,2,3)])
print('索引结果为:',arr[1:,(0,2,3)]) #索引第2、3行中第0、2、3列的元素
mask = np.array([1,0,1],dtype = np.bool)
#mask是一个布尔数组,它索引第1、3行中第2列的元素
print('索引结果为:',arr[mask,2])
Out[22]:
索引结果为: [ 2 6 10]
索引结果为: [[ 4 6 7]
[ 7 9 10]]
索引结果为: [3 9]
变换数组的形态
- 改变数组形状
Int[23]:
arr = np.arange(12) #创建一维数组
print('创建的一维数组为:',arr)
print('新的一维数组为:',arr.reshape(3,4)) #设置数组的形状
print('数组维度为:',arr.reshape(3,4).ndim) #查看数组维度
Out[23]:
创建的一维数组为: [ 0 1 2 3 4 5 6 7 8 9 10 11]
新的一维数组为: [[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
数组维度为: 2
- 使用ravel函数展平数组
Int[24]:
arr = np.arange(12).reshape(3,4)
print('创建的二维数组为:',arr)
print('数组展平后为:',arr.ravel())
Out[24]:
创建的二维数组为:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
数组展平后为: [ 0 1 2 3 4 5 6 7 8 9 10 11]
- 使用flatten函数展平数组
Int[25]:
print('数组展平为:',arr.flatten()) #横向展平
print('数组展平为:',arr.flatten('F')) #纵向展平
Out[25]:
数组展平为: [ 0 1 2 3 4 5 6 7 8 9 10 11]
数组展平为: [ 0 4 8 1 5 9 2 6 10 3 7 11]
-
组合数组
- 使用hstack函数实现数组横向组合:np.hstack((arr1,arr2))
- 使用vstack函数实现数组纵向组合:np.vstack((arr1,arr2))
- 使用concatenate函数实现数组横向组合:np.concatenate((arr1,arr2),axis = 1))
- 使用concatenate函数实现数组纵向组合:np.concatenate((arr1,arr2),axis = 0))
-
切割数组
- 使用hsplit函数实现数组横向分割: np.hsplit(arr1, 2)
- 使用vsplit函数实现数组纵向分割: np.vsplit(arr, 2)
- 使用split函数实现数组横向分割: np.split(arr, 2, axis=1)
- 使用split函数实现数组纵向分割: np.split(arr, 2, axis=0)
掌握 NumPy 矩阵与通用函数
创建NumPy矩阵
-
创建与组合矩阵
- 使用mat函数创建矩阵: matr1 = np.mat(“1 2 3;4 5 6;7 8 9”)
- 使用matrix函数创建矩阵:matr2 = np.matrix([[123],[456],[789]])
- 使用bmat函数合成矩阵:np.bmat(“arr1 arr2; arr1 arr2”)
-
矩阵的运算
- 矩阵与数相乘:matr1*3
- 矩阵相加减:matr1±matr2
- 矩阵相乘:matr1*matr2
- 矩阵对应元素相乘:np.multiply(matr1,matr2)
矩阵特有属性:
属性 | 说明 |
---|---|
T | 返回自身的转置 |
H | 返回自身的共轭转置 |
I | 返回自身的逆矩阵 |
A | 返回自身数据的2维数组的一个视图 |
认识ufunc函数
全称通用函数(universal function),是一种能够对数组中所有元素进行操作的函数。
- 四则运算:加(+)、减(-)、乘(*)、除(/)、幂(**)。数组间的四则运算表示对每个数组中的元素分别进行四则运算,所以形状必须相同。
- 比较运算:>、<、==、>=、<=、!=。比较运算返回的结果是一个布尔数组,每个元素为每个数组对应元素的比较结果。
- 逻辑运算:np.any函数表示逻辑“or”,np.all函数表示逻辑“and”。运算结果返回布尔值。
- ufunc函数的广播机制
- 广播(broadcasting)是指不同形状的数组之间执行算术运算的方式。需要遵循4个原则。
- 让所有输入数组都向其中shape最长的数组看齐,shape中不足的部分都通过在前面加1补齐。
- 出数组的shape是输入数组shape的各个轴上的最大值。
- 如果输入数组的某个轴和输出数组的对应轴的长度相同或者其长度为1时,这个数组能够用来计算,否则出错。
- 当输入数组的某个轴的长度为1时,沿着此轴运算时都用此轴上的第一组值。
# 一维数组的广播机制
[0 0 0] [0 0 0] [1 2 3] [1 2 3]
[1 1 1] [1 1 1] [1 2 3] [2 3 4]
[2 2 2] + [1 2 3] -> [2 2 2] + [1 2 3] = [3 4 5]
[3 3 3] [3 3 3] [1 2 3] [4 5 6]
# 二维数组的广播机制
[0 0 0] [1] [0 0 0] [1 1 1] [1 1 1]
[1 1 1] [2] [1 1 1] [2 2 2] [3 3 3]
[2 2 2] + [3] -> [2 2 2] + [3 3 3] = [5 5 5]
[3 3 3] [4] [3 3 3] [4 4 4] [7 7 7]
利用 NumPy 进行统计分析
读写文件
-
NumPy文件读写主要有二进制的文件读写和文件列表形式的数据读写两种形式
- save函数是以二进制的格式保存数据。 np.save(“…/tmp/save_arr”,arr)
- load函数是从二进制的文件中读取数据。 np.load(“…/tmp/save_arr.npy”)
- savez函数可以将多个数组保存到一个文件中。 np.savez(‘…/tmp/savez_arr’,arr1,arr2)
- 存储时可以省略扩展名,但读取时不能省略扩展名。
-
读取文本格式的数据
-
savetxt函数是将数组写到某种分隔符隔开的文本文件中。
np.savetxt(“…/tmp/arr.txt”, arr, fmt=“%d”, delimiter=“,”) -
loadtxt函数执行的是把文件加载到一个二维数组中。
np.loadtxt(“…/tmp/arr.txt”,delimiter=“,”) -
genfromtxt函数面向的是结构化数组和缺失数据。
np.genfromtxt(“…/tmp/arr.txt”, delimiter = “,”)
-
使用数组进行简单统计分析
-
直接排序
- sort函数是最常用的排序方法。 arr.sort()
- sort函数也可以指定一个axis参数,使得sort函数可以沿着指定轴对数据集进行排序。axis=1为沿横轴排序; axis=0为沿纵轴排序。
-
间接排序
- argsort函数返回值为重新排序值的下标。 arr.argsort()
- lexsort函数返回值是按照最后一个传入数据排序的。 np.lexsort((a,b,c))
-
去重与重复数据
- 通过unique函数可以找出数组中的唯一值并返回已排序的结果。
- tile函数主要有两个参数,参数“A”指定重复的数组,参数“reps”指定重复的次数。
np.tile(A,reps)
- repeat函数主要有三个参数,参数“a”是需要重复的数组元素,参数“repeats”是重复次数,参数“axis”指定沿着哪个轴进行重复,axis = 0表示按行进行元素重复;axis = 1表示按列进行元素重复。
numpy.repeat(a, repeats, axis=None)
- 这两个函数的主要区别在于,tile函数是对数组进行重复操作,repeat函数是对数组中的每个元素进行重复操作。
常用的统计函数
当axis=0时,表示沿着纵轴计算。当axis=1时,表示沿着横轴计算。默认时计算一个总值。
函数 | 说明 |
---|---|
sum | 计算数组的和 |
mean | 计算数组均值 |
std | 计算数组标准差 |
var | 计算数组方差 |
min | 计算数组最小值 |
max | 计算数组最大值 |
argmin | 返回数组最小元素的索引 |
argmax | 返回数组最小元素的索引 |
cumsum | 计算所有元素的累计和 |
cumprod | 计算所有元素的累计积 |
任务实现
读取iris数据集中的花萼长度数据(已保存为csv格式),并对其进行排序、去重,并求出和、累积和、均值、标准差、方差、最小值、最大值
Matplotlib数据可视化基础
了解绘图基础语法与常用参数
掌握pyplot基础语法
- 基本绘图流程
|<————————————第一部分————————————>|<———————————————第二部分——————————————>|<————————————第三部分————————————>|
____________________________否__________________
| _____________________ |
__ _v_ | | __ __ | __ __
创 选 | [添加标题] | 绘 添 | 保 显
作 ----> [是否创建子图]-是---->定 ---->| [添加x轴名称] |-->制 -->加--> [是否绘制完成] -是-> 存 -> 示
画 | 子 | [修改x轴刻度与范围] | 图 图 图 图
布 | 图 | [添加y轴名称] | 形 例 形 形
—— | —— | [修改y轴刻度与范围] | —— —— —— ——
| | |
| ——————————————————————
| ^
|__否____________________________|
- 创建画布与创建子图
第一部分主要作用是构建出一张空白的画布,并可以选择是否将整个画布划分为多个部分,方便在同一幅图上绘制多个图形的情况。最简单的绘图可以省略第一部分,而后直接在默认的画布上进行图形绘制。
函数名称 | 函数作用 |
---|---|
plt.figure | 创建一个空白画布,可以指定画布大小,像素。 |
figure.add_subplot | 创建并选中子图,可以指定子图的行数,列数,与选中图片编号。 |
- 添加画布内容
第二部分是绘图的主体部分。其中添加标题,坐标轴名称,绘制图形等步骤是并列的,没有先后顺序,可以先绘制图形,也可以先添加各类标签。但是添加图例一定要在绘制图形之后。
函数名称 | 函数作用 |
---|---|
plt.title | 在当前图形中添加标题,可以指定标题的名称、位置、颜色、字体大小等参数。 |
plt.xlabel | 在当前图形中添加x轴名称,可以指定位置、颜色、字体大小等参数。 |
plt.ylabel | 在当前图形中添加y轴名称,可以指定位置、颜色、字体大小等参数。 |
plt.xlim | 指定当前图形x轴的范围,只能确定一个数值区间,而无法使用字符串标识。 |
plt.ylim | 指定当前图形y轴的范围,只能确定一个数值区间,而无法使用字符串标识。 |
plt.xticks | 指定x轴刻度的数目与取值。 |
plt.yticks | 指定y轴刻度的数目与取值。 |
plt.legend | 指定当前图形的图例,可以指定图例的大小、位置、标签。 |
- 存与展示图形
第三部分主要用于保存和显示图形。
函数名称 | 函数作用 |
---|---|
plt.savafig | 保存绘制的图片,可以指定图片的分辨率、边缘的颜色等参数。 |
plt.show | 在本机显示图形。 |
设置pyplot的动态rc参数
- pyplot使用rc配置文件来自定义图形的各种默认属性,被称为rc配置或rc参数。
- 在pyplot中几乎所有的默认属性都是可以控制的,例如视图窗口大小以及每英寸点数、线条宽度、颜色和样式、坐标轴、坐标和网格属性、文本、字体等。
线条的常用rc参数名称、解释与取值
rc参数名称 | 解释 | 取值 |
---|---|---|
lines.linewidth | 线条宽度 | 取0-10之间的数值,默认为1.5。 |
lines.linestyle | 线条样式 | 可取“-”“–”“-.”“:”四种。默认为“-” |
lines.marker | 线条上点的形状 | 可取“o”“D”“h”“.”“,”“S”等20种,默认为None。 |
lines.markersize | 点的大小 | 取0-10之间的数值,默认为1。 |
常用线条类型解释
linestyle取值 | 意义 | linestyle取值 | 意义 |
---|---|---|---|
- | 实线 | -. | 点线 |
– | 长虚线 | : | 短虚线 |
线条标记解释
marker取值 | 意义 | marker取值 | 意义 |
---|---|---|---|
‘o’ | 圆圈 | ‘.’ | 点 |
‘D’ | 菱形 | ‘s’ | 正方形 |
‘h’ | 六边形1 | ‘*’ | 星号 |
‘H’ | 六边形2 | ‘d’ | 小菱形 |
‘-’ | 水平线 | ‘v’ | 一角朝下的三角形 |
‘8’ | 八边形 | ‘<’ | 一角朝左的三角形 |
‘p’ | 五边形 | ‘>’ | 一角朝右的三角形 |
‘,’ | 像素 | ‘^’ | 一角朝上的三角形 |
‘+’ | 加号 | ‘\’ | 竖线 |
‘None’ | 无 | ‘x’ | X |
注意事项
- 由于默认的pyplot字体并不支持中文字符的显示,因此需要通过设置font.sans-serif参数改变绘图时的字体,使得图形可以正常显示中文。同时,由于更改字体后,会导致坐标轴中的部分字符无法显示,因此需要同时更改axes.unicode_minus参数。
- 除了设置线条和字体的rc参数外,还有设置文本、箱线图、坐标轴、刻度、图例、标记、图片、图像保存等rc参数。具体参数与取值可以参考官方文档。
分析特征间的关系
绘制散点图
散点图
- 散点图(scatter diagram)又称为散点分布图,是以一个特征为横坐标,另一个特征为纵坐标,利用坐标点(散点)的分布形态反映特征间的统计关系的一种图形。
- 值是由点在图表中的位置表示,类别是由图表中的不同标记表示,通常用于比较跨类别的数据。
scatter函数
matplotlib.pyplot.scatter(x, y, s=None, c=None, marker=None, alpha=None, **kwargs)
- 常用参数及说明如下表所示。
参数名称 | 说明 |
---|---|
x,y | 接收array。表示x轴和y轴对应的数据。无默认。 |
s | 接收数值或者一维的array。指定点的大小,若传入一维array则表示每个点的大小。默认为None。 |
c | 接收颜色或者一维的array。指定点的颜色,若传入一维array则表示每个点的颜色。默认为None |
marker | 接收特定string。表示绘制的点的类型。默认为None。 |
alpha | 接收0-1的小数。表示点的透明度。默认为None。 |
绘制折线图
折线图
- 折线图(line chart)是一种将数据点按照顺序连接起来的图形。可以看作是将散点图,按照x轴坐标顺序连接起来的图形。
- 折线图的主要功能是查看因变量y随着自变量x改变的趋势,最适合用于显示随时间(根据常用比例设置)而变化的连续数据。同时还可以看出数量的差异,增长趋势的变化。
plot函数
matplotlib.pyplot.plot(*args, **kwargs)
- plot函数在官方文档的语法中只要求填入不定长参数,实际可以填入的主要参数主要如下。
参数名称 | 说明 |
---|---|
x,y | 接收array。表示x轴和y轴对应的数据。无默认。 |
color | 接收特定string。指定线条的颜色。默认为None。 |
linestyle | 接收特定string。指定线条类型。默认为“-”。 |
marker | 接收特定string。表示绘制的点的类型。默认为None。 |
alpha | 接收0-1的小数。表示点的透明度。默认为None。 |
- color参数的8种常用颜色的缩写。
颜色缩写 | 代表的颜色 | 颜色缩写 | 代表的颜色 |
---|---|---|---|
b | 蓝色 | m | 品红 |
g | 绿色 | y | 黄色 |
r | 红色 | k | 黑色 |
c | 青色 | w | 白色 |
任务实现
- 绘制2000-2017各产业与行业的国民生产总值散点图
-
国民生产总值数据总共有三大产业的国民生产总值,以及农业、工业、建筑、批发、交通、餐饮、金融、房地产和其他行业各个季度的增加值。
-
通过散点图分析三大行业的国民生产总值可以发现我国产业结构。通过比较各行业间季度的增加值则可以发现国民经济的主要贡献行业。
plt.figure(figsize=(8,7))## 设置画布
## 绘制散点1
plt.scatter(values[:,0],values[:,3], marker='o',c='red')
## 绘制散点2
plt.scatter(values[:,0],values[:,4], marker='D',c='blue')
## 绘制散点3
plt.scatter(values[:,0],values[:,5], marker='v',c='yellow')
plt.xlabel('年份')## 添加横轴标签
plt.ylabel('生产总值(亿元)')## 添加纵轴标签
plt.xticks(range(0,70,4),values[range(0,70,4),1],rotation=45)
plt.title('2000-2017年各产业季度生产总值散点图')## 添加图表标题
plt.legend(['第一产业','第二产业','第三产业'])## 添加图例
plt.savefig('../tmp/2000-2017年各产业季度生产总值散点图.png')
plt.show()
- 绘制2000-2017各产业与行业的国民生产总值折线图
- 通过绘制2000-2017各产业与行业的国民生产总值折线图,分别能够发现我国经济各产业与各行业增长趋势。
plt.figure(figsize=(8,7))
#绘制折线图
plt.plot(values[:,0], values[:,3], 'bs-', values[:,0], values[:,4], 'ro-.', values[:,0], values[:,5], 'gh--')
plt.xlabel('年份')## 添加横轴标签
plt.ylabel('生产总值(亿元)')## 添加y轴名称
plt.xticks(range(0,70,4),values[range(0,70,4),1],rotation=45)
plt.title('2000-2017年各产业季度生产总值折线图')## 添加图表标题
plt.legend(['第一产业','第二产业','第三产业'])
plt.show()
分析特征内部数据分布与分散状况
绘制直方图
直方图
-
直方图(Histogram)又称质量分布图,是统计报告图的一种,由一系列高度不等的纵向条纹或线段表示数据分布的情况,一般用横轴表示数据所属类别,纵轴表示数量或者占比。
-
用直方图可以比较直观地看出产品质量特性的分布状态,便于判断其总体质量分布情况。直方图可以发现分布表无法发现的数据模式、样本的频率分布和总体的分布。
bar函数
matplotlib.pyplot.bar(left,height,width = 0.8,bottom = None,hold = None,data = None,** kwargs )
- 常用参数及说明如下表所示。
参数名称 | 说明 |
---|---|
left | 接收array。表示x轴数据。无默认。 |
height | 接收array。表示x轴所代表数据的数量。无默认。 |
width | 接收0-1之间的float。指定直方图宽度。默认为0.8。 |
color | 接收特定string或者包含颜色字符串的array。表示直方图颜色。默认为None。 |
绘制饼图
饼图
-
饼图(Pie Graph)是将各项的大小与各项总和的比例显示在一张“饼”中,以“饼”的大小来确定每一项的占比。
-
饼图可以比较清楚地反映出部分与部分、部分与整体之间的比例关系,易于显示每组数据相对于总数的大小,而且显现方式直观。
pie函数
matplotlib.pyplot.pie(x, explode=None, labels=None, colors=None, autopct=None, pctdistance=0.6, shadow=False, labeldistance=1.1, startangle=None, radius=None, … )
- 常用参数及说明如下表所示。
参数名称 | 说明 | 参数名称 | 说明 |
---|---|---|---|
x | 接收array。表示用于绘制撇的数据。无默认。 | autopct | 接收特定string。指定数值的显示方式。默认为None。 |
explode | 接收array。表示指定项离饼图圆心为n个半径。默认为None。 | pctdistance | 接收float。指定每一项的比例和距离饼图圆心n个半径。默认为0.6。 |
labels | 接收array。指定每一项的名称。默认为None。 | labeldistance | 接收float。指定每一项的名称和距离饼图圆心多少个半径。默认为1.1。 |
color | 接收特定string或者包含颜色字符串的array。表示饼图颜色。默认为None。 | radius | 接收float。表示饼图的半径。默认为1。 |
绘制箱线图
箱线图
-
箱线图(boxplot)也称箱须图,其绘制需使用常用的统计量,能提供有关数据位置和分散情况的关键信息,尤其在比较不同特征时,更可表现其分散程度差异。
-
箱线图利用数据中的五个统计量(最小值、下四分位数、中位数、上四分位数和最大值)来描述数据,它也可以粗略地看出数据是否具有对称性、分布的分散程度等信息,特别可以用于对几个样本的比较。
boxplot函数
matplotlib.pyplot.boxplot(x, notch=None, sym=None, vert=None, whis=None, positions=None, widths=None, patch_artist=None,meanline=None, labels=None, … )
- 常用参数及说明如下表所示。
参数名称 | 说明 | 参数名称 | 说明 |
---|---|---|---|
x | 接收array。表示用于绘制箱线图的数据。无默认。 | positions | 接收array。表示图形位置。默认为None。 |
notch | 接收boolean。表示中间箱体是否有缺口。默认为None。 | widths | 接收scalar或者array。表示每个箱体的宽度。默认为None。 |
sym | 接收特定sting。指定异常点形状。默认为None。 | labels | 接收array。指定每一个箱线图的标签。默认为None。 |
vert | 接收boolean。表示图形是横向纵向或者横向。默认为None。 | meanline | 接收boolean。表示是否显示均值线。默认为False。 |
任务实现
- 绘制国民生产总值构成分布直方图
-
通过直方图分析2000年第一季度和2017年第一季度之间的三大产业的国民生产总值,可以发现各产业绝对数值之间的关系,并通过对比发现产业结构的变化。
-
同理可以得出行业间的绝对数值关系以及17年来行业发展状况。
- 绘制国民生产总值构成分布饼图
- 通过分析2000年与2017年不同的产业和行业在国民生产总值中的占比,可以发现我国产业结构变化和行业变迁。
- 绘制国民生产总值分散情况箱线图
- 通过分析2000年至2017年不同的产业和行业在国民生产总值中的分散情况,可以发现整体分散情况,从而判断整体增速是否加快。
小结
本章以2000至2017年各季度国民生产总值数据为例,介绍了pyplot绘图的基本语法,常用参数。
- 介绍了分析特征间相关关系的散点图。
- 分析特征间趋势关系的折线图。
- 分析特征内部数据分布的直方图和饼状图。
- 以及分析特征内部数据分散情况的箱线图。
为读者后续深入学习Matplotlib数据可视化打下了深厚的基础。
pandas统计分析基础
读写不同数据源的数据
数据库数据读取
-
pandas提供了读取与存储关系型数据库数据的函数与方法。除了pandas库外,还需要使用SQLAlchemy库建立对应的数据库连接。SQLAlchemy配合相应数据库的Python连接工具(例如MySQL数据库需要安装mysqlclient或者pymysql库),使用create_engine函数,建立一个数据库连接。
-
creat_engine中填入的是一个连接字符串。在使用Python的SQLAlchemy时,MySQL和Oracle数据库连接字符串的格式如下
数据库产品名+连接工具名://用户名:密码@数据库IP地址:数据库端口号/数据库名称?charset = 数据库数据编码
- read_sql_table只能够读取数据库的某一个表格,不能实现查询的操作。
pandas.read_sql_table(table_name, con, schema=None, index_col=None, coerce_float=True, columns=None)
- read_sql_query则只能实现查询操作,不能直接读取数据库中的某个表。
pandas.read_sql_query(sql, con, index_col=None, coerce_float=True)
- read_sql是两者的综合,既能够读取数据库中的某一个表,也能够实现查询操作。
pandas.read_sql(sql, con, index_col=None, coerce_float=True, columns=None)
- pandas三个数据库数据读取函数的参数几乎完全一致,唯一的区别在于传入的是语句还是表名。
参数名称 | 说明 |
---|---|
sql or table_name | 接收string。表示读取的数据的表名或者sql语句。无默认。 |
con | 接收数据库连接。表示数据库连接信息。无默认 |
index_col | 接收int,sequence或者False。表示设定的列作为行名,如果是一个数列则是多重索引。默认为None。 |
coerce_float | 接收boolean。将数据库中的decimal类型的数据转换为pandas中的float64类型的数据。默认为True。 |
columns | 接收list。表示读取数据的列名。默认为None。 |
数据库数据存储
- 数据库数据读取有三个函数,但数据存储则只有一个to_sql方法。
DataFrame.to_sql(name, con, schema=None, if_exists=’fail’, index=True, index_label=None, dtype=None)
参数名称 | 说明 |
---|---|
name | 接收string。代表数据库表名。无默认。 |
con | 接收数据库连接。无默认。 |
if_exists | 接收fail,replace,append。fail表示如果表名存在则不执行写入操作;replace表示如果存在,将原数据库表删除,再重新创建;append则表示在原数据库表的基础上追加数据。默认为fail。 |
index | 接收boolean。表示是否将行索引作为数据传入数据库。默认True。 |
index_label | 接收string或者sequence。代表是否引用索引名称,如果index参数为True此参数为None则使用默认名称。如果为多重索引必须使用sequence形式。默认为None。 |
dtype | 接收dict。代表写入的数据类型(列名为key,数据格式为values)。默认为None。 |
读写文本文件
- 文本文件读取
-
文本文件是一种由若干行字符构成的计算机文件,它是一种典型的顺序文件。
-
csv是一种逗号分隔的文件格式,因为其分隔符不一定是逗号,又被称为字符分隔文件,文件以纯文本形式存储表格数据(数字和文本)。
-
使用read_table来读取文本文件。
pandas.read_table(filepath_or_buffer, sep=’\t’, header=’infer’, names=None, index_col=None, dtype=None, engine=None, nrows=None)
- 使用read_csv函数来读取csv文件。
pandas.read_csv(filepath_or_buffer, sep=’\t’, header=’infer’, names=None, index_col=None, dtype=None, engine=None, nrows=None)
- read_table和read_csv常用参数及其说明。
参数名称 | 说明 |
---|---|
filepath | 接收string。代表文件路径。无默认。 |
sep | 接收string。代表分隔符。read_csv默认为“,”,read_table默认为制表符“[Tab]”。 |
header | 接收int或sequence。表示将某行数据作为列名。默认为infer,表示自动识别。 |
names | 接收array。表示列名。默认为None。 |
index_col | 接收int、sequence或False。表示索引列的位置,取值为sequence则代表多重索引。默认为None。 |
dtype | 接收dict。代表写入的数据类型(列名为key,数据格式为values)。默认为None。 |
engine | 接收c或者python。代表数据解析引擎。默认为c。 |
nrows | 接收int。表示读取前n行。默认为None。 |
- read_table和read_csv函数中的sep参数是指定文本的分隔符的,如果分隔符指定错误,在读取数据的时候,每一行数据将连成一片。
- header参数是用来指定列名的,如果是None则会添加一个默认的列名。
- encoding代表文件的编码格式,常用的编码有utf-8、utf-16、gbk、gb2312、gb18030等。如果编码指定错误数据将无法读取,IPython解释器会报解析错误。
- 文本文件储存
- 文本文件的存储和读取类似,结构化数据可以通过pandas中的to_csv函数实现以csv文件格式存储文件。
DataFrame.to_csv(path_or_buf=None, sep=’,’, na_rep=”, columns=None, header=True, index=True,index_label=None,mode=’w’,encoding=None)
参数名称 | 说明 | 参数名称 | 说明 |
---|---|---|---|
path_or_buf | 接收string。代表文件路径。无默认。 | index | 接收boolean,代表是否将行名(索引)写出。默认为True。 |
sep | 接收string。代表分隔符。默认为“,”。 | index_labels | 接收sequence。表示索引名。默认为None。 |
na_rep | 接收string。代表缺失值。默认为“”。 | mode | 接收特定string。代表数据写入模式。默认为w。 |
columns | 接收list。代表写出的列名。默认为None。 | encoding | 接收特定string。代表存储文件的编码格式。默认为None。 |
header | 接收boolean,代表是否将列名写出。默认为True。 |
读写Excel文件
- Excel文件读取
- pandas提供了read_excel函数来读取“xls”“xlsx”两种Excel文件。
pandas.read_excel(io, sheetname=0, header=0, index_col=None, names=None, dtype=None)
参数名称 | 说明 |
---|---|
io | 接收string。表示文件路径。无默认。 |
sheetname | 接收string、int。代表excel表内数据的分表位置。默认为0。 |
header | 接收int或sequence。表示将某行数据作为列名。默认为infer,表示自动识别。 |
names | 接收int、sequence或者False。表示索引列的位置,取值为sequence则代表多重索引。默认为None。 |
index_col | 接收int、sequence或者False。表示索引列的位置,取值为sequence则代表多重索引。默认为None。 |
dtype | 接收dict。代表写入的数据类型(列名为key,数据格式为values)。默认为None。 |
- Excel文件储存
- 将文件存储为Excel文件,可以使用to_excel方法。其语法格式如下。
DataFrame.to_excel(excel_writer=None, sheetname=None’, na_rep=”, header=True, index=True, index_label=None, mode=’w’, encoding=None)
- to_csv方法的常用参数基本一致,区别之处在于指定存储文件的文件路径参数名称为excel_writer,并且没有sep参数,增加了一个sheetnames参数用来指定存储的Excel sheet的名称,默认为sheet1。
掌握DataFrame的常用操作
基础属性
函数 | 返回值 |
---|---|
values | 元素 |
index | 索引 |
columns | 列名 |
dtypes | 类型 |
size | 元素个数 |
ndim | 维度数 |
shape | 数据形状(行列数目) |
查改增删DataFrame数据
- 查看访问DataFrame中的数据——数据基本查看方式
-
对单列数据的访问:DataFrame的单列数据为一个Series。根据DataFrame的定义可以知晓DataFrame是一个带有标签的二维数组,每个标签相当每一列的列名。有以下两种方式来实现对单列数据的访问。
- 以字典访问某一个key的值的方式使用对应的列名,实现单列数据的访问。
- 以属性的方式访问,实现单列数据的访问。(不建议使用,易引起混淆)
-
对某一列的某几行访问:访问DataFrame中某一列的某几行时,单独一列的DataFrame可以视为一个Series(另一种pandas提供的类,可以看作是只有一列的DataFrame),而访问一个Series基本和访问一个一维的ndarray相同。
-
对多列数据访问:访问DataFrame多列数据可以将多个列索引名称视为一个列表,同时访问DataFrame多列数据中的多行数据和访问单列数据的多行数据方法基本相同。
-
对某几行访问:
- 如果只是需要访问DataFrame某几行数据的实现方式则和上述的访问多列多行相似,选择所有列,使用“:”代替即可。
- head和tail也可以得到多行数据,但是用这两种方法得到的数据都是从开始或者末尾获取的连续数据。
- 默认参数为访问5行,只要在方法后方的“()”中填入访问行数即可实现目标行数的查看。
- 查看访问DataFrame中的数据——loc,iloc访问方式
- loc方法是针对DataFrame索引名称的切片方法,如果传入的不是索引名称,那么切片操作将无法执行。利用loc方法,能够实现所有单层索引切片操作。loc方法使用方法如下。
DataFrame.loc[行索引名称或条件, 列索引名称]
- iloc和loc区别是iloc接收的必须是行索引和列索引的位置。iloc方法的使用方法如下。
DataFrame.iloc[行索引位置, 列索引位置]
-
使用loc方法和iloc实现多列切片,其原理的通俗解释就是将多列的列名或者位置作为一个列表或者数据传入。
-
使用loc,iloc方法可以取出DataFrame中的任意数据。
-
在loc使用的时候内部传入的行索引名称如果为一个区间,则前后均为闭区间;iloc方法使用时内部传入的行索引位置或列索引位置为区间时,则为前闭后开区间。
-
loc内部还可以传入表达式,结果会返回满足表达式的所有值。
-
若使用detail.iloc[detail[‘order_id’]‘458’,[1,5]]读取数据,则会报错,原因在于此处条件返回的为一个布尔值Series,而iloc可以接收的数据类型并不包括Series。根据Series的构成只要取出该Series的values就可以了。需改为detail.iloc[(detail[‘order_id’]‘458’).values,[1,5]])。
-
loc更加灵活多变,代码的可读性更高,iloc的代码简洁,但可读性不高。具体在数据分析工作中使用哪一种方法,根据情况而定,大多数时候建议使用loc方法。
- 查看访问DataFrame中的数据——切片方法之ix
- ix方法更像是loc和iloc两种切片方法的融合。ix方法在使用时既可以接收索引名称也可以接收索引位置。其使用方法如下。
DataFrame.ix[行索引的名称或位置或者条件, 列索引名称或位置]
- 使用ix方法时有个注意事项,第一条,当索引名称和位置存在部分重叠时,ix默认优先识别名称。
控制ix方法需要注意以下几点。
- 使用ix参数时,尽量保持行索引名称和行索引位置重叠,使用时就无须考虑取值时区间的问题。一律为闭区间。
- 使用列索引名称,而非列索引位置。主要用来保证代码可读性。
- 使用列索引位置时,需要注解。同样保证代码可读性。
- 除此之外ix方法还有一个缺点,就是在面对数据量巨大的任务的时候,其效率会低于loc和iloc方法,所以在日常的数据分析工作中建议使用loc和iloc方法来执行切片操作。
- 更新修改DataFrame中的数据
- 更改DataFrame中的数据,原理是将这部分数据提取出来,重新赋值为新的数据。
- 需要注意的是,数据更改直接针对DataFrame原数据更改,操作无法撤销,如果做出更改,需要对更改条件做确认或对数据进行备份。
- 为DataFrame增添数据
- DataFrame添加一列的方法非常简单,只需要新建一个列索引。并对该索引下的数据进行赋值操作即可。
- 新增的一列值是相同的则直接赋值一个常量即可。
- 删除某列或某行数据
- 删除某列或某行数据需要用到pandas提供的方法drop,drop方法的用法如下。
- axis为0时表示删除行,axis为1时表示删除列。
drop(labels, axis=0, level=None, inplace=False, errors='raise')
- 常用参数如下所示。
参数名称 | 说明 |
---|---|
labels | 接收string或array。代表删除的行或列的标签。无默认。 |
axis | 接收0或1。代表操作的轴向。默认为0。 |
levels | 接收int或者索引名。代表标签所在级别。默认为None。 |
inplace | 接收boolean。代表操作是否对原数据生效。默认为False。 |
描述分析DataFrame数据
- 数值型特征的描述性统计——NumPy中的描述性统计函数
- 数值型数据的描述性统计主要包括了计算数值型数据的完整情况、最小值、均值、中位数、最大值、四分位数、极差、标准差、方差、协方差和变异系数等。在NumPy库中一些常用的统计学函数如下表所示。
- pandas库基于NumPy,自然也可以用这些函数对数据框进行描述性统计。
函数名称 | 说明 | 函数名称 | 说明 |
---|---|---|---|
np.min | 最小值 | np.max | 最大值 |
np.mean | 均值 | np.ptp | 极差 |
np.median | 中位数 | np.std | 标准差 |
np.var | 方差 | np.cov | 协方差 |
- 数值型特征的描述性统计—— pandas描述性统计方法
- pandas还提供了更加便利的方法来计算均值 ,如detail[‘amounts’].mean()。
- pandas还提供了一个方法叫作describe,能够一次性得出数据框所有数值型特征的非空值数目、均值、四分位数、标准差。
方法名称 | 说明 | 方法名称 | 说明 |
---|---|---|---|
min | 最小值 | max | 最大值 |
mean | 均值 | ptp | 极差 |
median | 中位数 | std | 标准差 |
var | 方差 | cov | 协方差 |
sem | 标准误差 | mode | 众数 |
skew | 样本偏度 | kurt | 样本峰度 |
quantile | 四分位数 | count | 非空值数目 |
describe | 描述统计 | mad | 平均绝对离差 |
- 类别型特征的描述性统计
- 描述类别型特征的分布状况,可以使用频数统计表。pandas库中实现频数统计的方法为value_counts。
- pandas提供了categories类,可以使用astype方法将目标特征的数据类型转换为category类别。
- describe方法除了支持传统数值型以外,还能够支持对category类型的数据进行描述性统计,四个统计量分别为列非空元素的数目,类别的数目,数目最多的类别,数目最多类别的数目。
转换与处理时间序列数据
转换字符串时间为标准时间
- pandas时间相关的类
- 在多数情况下,对时间类型数据进行分析的前提就是将原本为字符串的时间转换为标准时间类型。
pandas继承了NumPy库和datetime库的时间相关模块
,提供了6种时间相关的类。
类名称 | 说明 |
---|---|
Timestamp | 最基础的时间类。表示某个时间点。在绝大多数的场景中的时间数据都是Timestamp形式的时间。 |
Period | 表示单个时间跨度,或者某个时间段,例如某一天,某一小时等。 |
Timedelta | 表示不同单位的时间,例如1天,1.5小时,3分钟,4秒等,而非具体的某个时间段。(做时间类型的计算) |
DatetimeIndex | 一组Timestamp构成的Index,可以用来作为Series或者DataFrame的索引。 |
PeriodtimeIndex | 一组Period构成的Index,可以用来作为Series或者DataFrame的索引。 |
TimedeltaIndex | 一组Timedelta构成的Index,可以用来作为Series或者DataFrame的索引。 |
- Timestamp类型
- 其中Timestamp作为时间类中最基础的,也是最为常用的。在多数情况下,时间相关的字符串都会转换成为Timestamp。pandas提供了to_datetime函数,能够实现这一目标。
- 值得注意的是,Timestamp类型时间是有限制的。
- DatetimeIndex与PeriodIndex函数
- 除了将数据字原始DataFrame中直接转换为Timestamp格式外,还可以将数据单独提取出来将其转换为DatetimeIndex或者PeriodIndex。
- 转换为PeriodIndex的时候需要注意,需要通过freq参数指定时间间隔,常用的时间间隔有Y为年,M为月,D为日,H为小时,T为分钟,S为秒。两个函数可以用来转换数据还可以用来创建时间序列数据,其参数非常类似。
- DatetimeIndex与PeriodIndex函数及其参数说明
- DatetimeIndex和PeriodIndex两者区别在日常使用的过程中相对较小,其中DatetimeIndex是用来指代一系列时间点的一种数据结构,而PeriodIndex则是用来指代一系列时间段的数据结构。
参数名称 | 说明 |
---|---|
data | 接收array。表示DatetimeIndex的值。无默认。 |
freq | 接收string。表示时间的间隔频率。无默认。 |
start | 接收string。表示生成规则时间数据的起始点。无默认。 |
periods | 表示需要生成的周期数目。无默认。 |
end | 接收string。表示生成规则时间数据的终结点。无默认。 |
tz | 接收timezone。表示数据的时区。默认为None。 |
name | 接收int,string。默认为空。指定DatetimeIndex的名字。 |
提取时间序列数据信息
- Timestamp类常用属性
- 在多数涉及时间相关的数据处理,统计分析的过程中,需要提取时间中的年份,月份等数据。使用对应的Timestamp类属性就能够实现这一目的。
- 结合Python列表推导式,可以实现对DataFrame某一列时间信息数据的提取。
属性名称 | 说明 | 属性名称 | 说明 |
---|---|---|---|
year | 年 | week | 一年中第几周 |
month | 月 | quarter | 季节 |
day | 日 | weekofyear | 一年中第几周 |
hour | 小时 | dayofyear | 一年中的第几天 |
minute | 分钟 | dayofweek | 一周第几天 |
second | 秒 | weekday | 一周第几天 |
date | 日期 | weekday_name | 星期名称 |
time | 时间 | is_leap_year | 是否闰年 |
- 在DatetimeIndex和PeriodIndex中提取信息
- 在DatetimeIndex和PeriodIndex中提取对应信息可以以类属性方式实现。
- 值得注意的是PeriodIndex相比于DatetimeIndex少了weekday_name属性,所以不能够用该属性提取星期名称数据。若想要提取信息名称可以通过提取weekday属性,而后将0-6四个标签分别赋值为Monday至Sunday。
加减时间数据
- Timedelta类
- Timedelta是时间相关的类中的一个异类,不仅能够使用正数,还能够使用负数表示单位时间,例如1秒,2分钟,3小时等。使用Timedelta类,配合常规的时间相关类能够轻松实现时间的算术运算。目前Timedelta函数中时间周期中没有年和月。所有周期名称,对应单位及其说明如下表所示。
周期名称 | 单位 | 说明 | 周期名称 | 单位 | 说明 |
---|---|---|---|---|---|
weeks | 无 | 星期 | seconds | s | 秒 |
days | D | 天 | milliseconds | ms | 毫秒 |
hours | h | 小时 | microseconds | us | 微妙 |
minutes | m | 分 | nanoseconds | ns | 纳秒 |
- 使用Timedelta ,可以很轻松地实现在某个时间上加减一段时间 。
- 除了使用Timedelta实现时间的平移外,还能够直接对两个时间序列进行相减,从而得出一个Timedelta。
使用分组聚合进行组内计算
使用groupby方法拆分数据
- groupby方法的参数及其说明
- 该方法提供的是分组聚合步骤中的拆分功能,能根据索引或字段对数据进行分组。其常用参数与使用格式如下。
DataFrame.groupby(by=None, axis=0, level=None, as_index=True, sort=True, group_keys=True, squeeze=False, **kwargs)
参数名称 | 说明 |
---|---|
by | 接收list,string,mapping或generator。用于确定进行分组的依据。无默认。 |
axis | 接收int。表示操作的轴向,默认对列进行操作。默认为0。 |
level | 接收int或者索引名。代表标签所在级别。默认为None。 |
as_index | 接收boolearn。表示聚合后的聚合标签是否以DataFrame索引形式输出。默认为True。 |
sort | 接收boolearn。表示是否对分组依据分组标签进行排序。默认为True。 |
group_keys | 接收boolearn。表示是否显示分组标签的名称。默认为True。 |
squeeze | 接收boolearn。表示是否在允许的情况下对返回数据进行降维。默认为False。 |
- groupby方法的参数及其说明——by参数的特别说明
- 如果传入的是一个函数则对索引进行计算并分组。
- 如果传入的是一个字典或者Series则字典或者Series的值用来做分组依据。
- 如果传入一个NumPy数组则数据的元素作为分组依据。
- 如果传入的是字符串或者字符串列表则使用这些字符串所代表的字段作为分组依据。
- GroupBy对象常用的描述性统计方法
- 用groupby方法分组后的结果并不能直接查看,而是被存在内存中,输出的是内存地址。实际上分组后的数据对象GroupBy类似Series与DataFrame,是pandas提供的一种对象。GroupBy对象常用的描述性统计方法如下。
方法名称 | 说明 | 方法名称 | 说明 |
---|---|---|---|
count | 计算分组的数目,包括缺失值。 | cumcount | 对每个分组中组员的进行标记,0至n-1。 |
head | 返回每组的前n个值。 | size | 返回每组的大小。 |
max | 返回每组最大值。 | min | 返回每组最小值。 |
mean | 返回每组的均值。 | std | 返回每组的标准差。 |
median | 返回每组的中位数。 | sum | 返回每组的和。 |
使用agg方法聚合数据
- agg和aggregate函数参数及其说明
- agg,aggregate方法都支持对每个分组应用某函数,包括Python内置函数或自定义函数。同时这两个方法能够也能够直接对DataFrame进行函数应用操作。
- 在正常使用过程中,agg函数和aggregate函数对DataFrame对象操作时功能几乎完全相同,因此只需要掌握其中一个函数即可。它们的参数说明如下表。
DataFrame.agg(func, axis=0, *args, **kwargs)
DataFrame.aggregate(func, axis=0, *args, **kwargs)
参数名称 | 说明 |
---|---|
func | 接收list、dict、function。表示应用于每行/每列的函数。无默认。 |
axis | 接收0或1。代表操作的轴向。默认为0。 |
- agg方法求统计量
- 可以使用agg方法一次求出当前数据中所有菜品销量和售价的总和与均值,如detail[[‘counts’,‘amounts’]].agg([np.sum,np.mean]))。
- 对于某个字段希望只做求均值操作,而对另一个字段则希望只做求和操作,可以使用字典的方式,将两个字段名分别作为key,然后将NumPy库的求和与求均值的函数分别作为value,如detail.agg({‘counts’:np.sum,‘amounts’:np.mean}))。
- 在某些时候还希望求出某个字段的多个统计量,某些字段则只需要求一个统计量,此时只需要将字典对应key的value变为列表,列表元素为多个目标的统计量即可,如detail.agg({‘counts’:np.sum,‘amounts’:[np.mean,np.sum]}))
- agg方法与自定义的函数
- 在agg方法可传入读者自定义的函数。
- 使用自定义函数需要注意的是NumPy库中的函数np.mean,np.median,np.prod,np.sum,np.std,np.var能够在agg中直接使用,但是在自定义函数中使用NumPy库中的这些函数,如果计算的时候是单个序列则会无法得出想要的结果,如果是多列数据同时计算则不会出现这种问题。
- 使用agg方法能够实现对每一个字段每一组使用相同的函数。
- 如果需要对不同的字段应用不同的函数,则可以和Dataframe中使用agg方法相同。
使用apply方法聚合数据
- apply方法类似agg方法能够将函数应用于每一列。不同之处在于apply方法相比agg方法传入的函数只能够作用于整个DataFrame或者Series,而无法像agg一样能够对不同字段,应用不同函数获取不同结果。
- 使用apply方法对GroupBy对象进行聚合操作其方法和agg方法也相同,只是使用agg方法能够实现对不同的字段进行应用不同的函数,而apply则不行。
DataFrame.apply(func, axis=0, broadcast=False, raw=False, reduce=None, args=(), **kwds)
参数名称 | 说明 |
---|---|
func | 接收functions。表示应用于每行/列的函数。无默认。 |
axis | 接收0或1。代表操作的轴向。默认为0。 |
broadcast | 接收boolearn。表示是否进行广播。默认为False。 |
raw | 接收boolearn。表示是否直接将ndarray对象传递给函数。默认为False。 |
reduce | 接收boolearn或者None。表示返回值的格式。默认None。 |
使用transform方法聚合数据
- transform方法能够对整个DataFrame的所有元素进行操作。且transform方法只有一个参数“func”,表示对DataFrame操作的函数。
- 同时transform方法还能够对DataFrame分组后的对象GroupBy进行操作,可以实现组内离差标准化等操作。
- 若在计算离差标准化的时候结果中有NaN,这是由于根据离差标准化公式,最大值和最小值相同的情况下分母是0。而分母为0的数在Python中表示为NaN。
创建透视表与交叉表
使用povit_table函数创建透视表
- pivot_table函数常用参数及其说明
- 利用pivot_table函数可以实现透视表,pivot_table()函数的常用参数及其使用格式如下。
pands.pivot_table(data, values=None, index=None, columns=None, aggfunc='mean', fill_value=None, margins=False, dropna=True, margins_name='All')
参数名称 | 说明 |
---|---|
data | 接收DataFrame。表示创建表的数据。无默认。 |
values | 接收字符串。用于指定想要聚合的数据字段名,默认使用全部数据。默认为None。 |
index | 接收string或list。表示行分组键。默认为None。 |
columns | 接收string或list。表示列分组键。默认为None。 |
aggfunc | 接收functions。表示聚合函数。默认为mean。 |
margins | 接收boolearn。表示汇总(Total)功能的开关,设为True后结果集中会出现名为“ALL”的行和列。默认为True。 |
dropna | 接收boolearn。表示是否删掉全为NaN的列。默认为False。 |
- pivot_table函数主要的参数调节
- 在不特殊指定聚合函数aggfunc时,会默认使用numpy.mean进行聚合运算,numpy.mean会自动过滤掉非数值类型数据。可以通过指定aggfunc参数修改聚合函数。
- 和groupby方法分组的时候相同,pivot_table函数在创建透视表的时候分组键index可以有多个。
- 通过设置columns参数可以指定列分组。
- 当全部数据列数很多时,若只想要显示某列,可以通过指定values参数来实现。
- 当某些数据不存在时,会自动填充NaN,因此可以指定fill_value参数,表示当存在缺失值时,以指定数值进行填充。
- 可以更改margins参数,查看汇总数据。
使用crosstab函数创建交叉表
- crosstab函数
- 交叉表是一种特殊的透视表,主要用于计算分组频率。利用pandas提供的crosstab函数可以制作交叉表,crosstab函数的常用参数和使用格式如下。
- 由于交叉表是透视表的一种,其参数基本保持一致,不同之处在于crosstab函数中的index,columns,values填入的都是对应的从Dataframe中取出的某一列。
pandas.crosstab(index, columns, values=None, rownames=None, colnames=None, aggfunc=None, margins=False, dropna=True, normalize=False)
- crosstab的常用参数及其说明
参数名称 | 说明 |
---|---|
index | 接收string或list。表示行索引键。无默认。 |
columns | 接收string或list。表示列索引键。无默认。 |
values | 接收array。表示聚合数据。默认为None。 |
aggfunc | 接收function。表示聚合函数。默认为None。 |
rownames | 表示行分组键名。无默认。 |
colnames | 表示列分组键名。无默认。 |
dropna | 接收boolearn。表示是否删掉全为NaN的。默认为False。 |
margins | 接收boolearn。默认为True。汇总(Total)功能的开关,设为True后结果集中会出现名为“ALL”的行和列。 |
normalize | 接收boolearn。表示是否对值进行标准化。默认为False。 |
小结
本章以餐饮数据为例
介绍了数据库数据,csv数据,Excel数据三种常用的数据读取与写入方式。
阐述了DataFrame的常用属性,方法与描述性统计相关内容。
介绍了时间数据的转换,信息提取与算术运算。
剖析了分组聚合方法groupby的原理,用法和三种聚合方法。
展现了透视表与交叉表的制作方法。
通过本章的学习,读者能够对pandas库有一个整体了解并能够利用pandas库进行基础的统计。