python数据分析入门详解!!!非常详细!!!

python数据分析可视化

python内存管理方式:基于值的内存管理

一.体验Numpy(数值计算)多维数组对象

numpy实现数组相加

import numpy as np
def plus(n):
    a = np.arange(1, n+1) ** 3
    b = np.arange(1,n+1) ** 2
    return a+b
print(plus(3))

1.1创建数组的方法

a = np.array([1,2,3])
a = np.arange(1,6)

array的属性

shape:返回一个元组,表示array的维度(几行几列)

ndim:返回一个数字,表示维度数

size:返回一个数字,表示数组中所欲数据元素的数目

dtype:返回数组中的数据类型

1.1.1arange创建数字序列

np.arange([开始,]结束[,步长],dtype=‘’)

eg. a = np.arange(1,10,2)=>[1 3 5 7 9]

​ a = np.array(range(1,10,2),dtype=‘int64’)=>[1 3 5 7 9]

1.1.2使用ones创建全1的数组

np.ones(shape,dtype=None,order=‘C’)//默认C语言

eg. a = np.ones((2,1))=>[[1.]
[1.]]

​ a = np.ones(3)=>[1,1,1,]

np.zeros()创建全0的数组

np.full(shape,fill_value,dtype,order)

eg. np.full(3,520)=>[520,520,520]

1.1.3创建形状相同的数组

np.ones_like(array):创建和arrays形状相同的全为1的数组

eg.

a = np.array([[1,2,3],[4,5,6]])
b = np.ones_like(a)
1.1.4使用random生成随机数组

np.random.rand()生成随机数,传1个数就是一维,2个数就是二维,…

eg.a = np.random.rand(3) =>[0.24580567 0.38861566 0.42000963]

​ b = np.random.rand(2,3) =>[[…,[…,…],[…,…,…]]

1.2多维数组

a = np.array([[1,2,3],[4,5,6]])

a.shape=>(2,3)二行三列的数组

三维数组(a,b,c)a块,b行,c列的数组

eg. a = np.ones((2,3,4))=>a.ndim=>3

1.2.1reshape不改值修改形状
a = np.arange(10).reshape(2,5)

将一维数组[0,1,2,3,4,5,6,7,8,9]转换为二维数组[[0,1,2,3,4],[5,6,7,8,9]]

1.2.2数组计算

a+1:数组中每个数加1

形状一样的数组:a+b:对应位置的数字相加

a(2,5)-b(1,5):将数组b看成一个两行相同数字的二维数组

a(2,5)-b(2,1):将数组b看成一个五列相同数字的二维数组

1.2.3广播原则

若两数组后缘维度相同,则可以将两个数组加减乘除

eg.(2,3)和)(3,); (3,4,2)和(4,2)

若两数组维度相同,则可以相加减(注:b的维度和a相同,但b的后缘维度不能超过a的后缘维度)

eg.(4,3)和(4,1)

eg.(3,2,2)和(2,4)不可以相加减

1.3基础索引

切片语法:序列[开始下标:结束下标:步长](不包括结束下标的数据)

eg. a = np.arange(10)

索引:a[5]=>5

切片:a[3:9]=>[3,4,5,6,7,8]

二维数组

import numpy as np
a = np.random.rand(20).reshape(4,5)
print(a)#四行五列的数组
print("-------------------")
print(a[-1])#二维数组的最后一行
print("-------------------")
print(a[0:-1])#二维数组除最后一行以外的其他行
print("-------------------")
print(a[0:2])#二维数组的0,1行
print("-------------------")
print(a[0:2,1:3])#二维数组的0,1行的1,2列

1.4布尔索引

一维数组:数组01化处理

import numpy as np
array = np.arange(10)
array[array<5]=0#小于5的数字为0
array[array>=5]=1#大于等于5的数字为1
print(array)

二维数组:把所有行的第三列变为520

import numpy as np
array = np.arange(1,21).reshape(4,5)
array[:,3]=520#所有行的第三列
print(array)

1.5神奇索引

一维数组

import numpy as np
array = np.arange(10)
print(array[[2,3,5]])

"[[]]"代表索引下标

二维数组

import numpy as np
array = np.arange(20).reshape(4,5)
print(array[[1,2]])#1,2行的数据

"[[]]"代表行下标

import numpy as np
array = np.arange(20).reshape(4,5)
print(array[[1,2],[4,3]])#取第一行第四列,第二行第三列
import numpy as np
array = np.arange(20).reshape(4,5)
print(array[:,[1,2]])#所有行的1,2列
import numpy as np
a = np.arange(30);
array = np.arange(20).reshape(4,5)
print(a)
print("--------------")
print(array)
print("--------------")
print(a[array])#一维数组无法按照切片拿出二维数组,所以结果是二维数字本身

二.Numpy的轴

1.一维数组:shape(4,):一个0轴

2.二维数组:shape(2,3):两个轴,行为0,列为1

3.三维数组:shape(4,3,2):三个轴,块为0,行为1,列为2

2.1沿轴切片

a[] = [[1,2,3],[4,5,6],[7,8,9]]

1.一个参数

print(a[:2]):第一个参数代表0轴,所以:2表示0轴,表示这个切片在二维维度上切的

2.两个参数

print(a[:2,1:]):第一个参数表示0轴,即0行到1行;第二个参数表示列,即1列到末尾

2.2传入轴编号

数组转置:a.transpose()

轴转置:a.swapaxes(1,0)//将数组0,1轴转置,即将数组转置

三.常用random随机函数

4.1seed

import random
random.seed(100)#添加种子后,随机数不变
print(random.random())#随机生成0-1之间的浮点数
print(random.random())

4.2rand

rand返回【0,1】之间

import numpy as np;
print(np.random.rand(3))
print(np.random.rand(2,3))#返回2行3列的随机数组(0-1)
print(np.random.rand(2,3,4))

4.3randn返回标准正态分布随机数(浮点数)

randn返回标准正态分布N(0,1),即平均数0,方差1

4.4randint返回随机整数

import  numpy as np
a = np.random.randint(3)
print(f"返回0-3之间的随机整数:{a}")
b = np.random.randint(1,3)
print(f"返回1-3之间的随机整数:{b}")
c = np.random.randint(1,10,size=(5,))
print(f"返回1-10之间5个随机数生成一维数组:\n{c}")
d = np.random.randint(1,20,size=(3,2))
print(f"返回1-20之间的随机数,生成2行三列二维数组:\n{d}")

4.5random

random生成0.0-1.0的随机数

import  numpy as np
a = np.random.random(3)
print(f"生成3个随机数:{a}")
b = np.random.random(size=(2,3))
print(f"生成随机二维数组2行3列:{b}")

4.5choice从一维数组中生成随机数

第一个参数是一个一维数组,一个数可看成range()

第二个参数是维度和元素个数

import  numpy as np
a = np.random.choice(5,2)
print(f"随机从range(5)中取2个数:{a}")
b = np.random.choice(5,(3,2))
print(f"随机从range(5)中取数得出2行3列数组:\n{b}")
c = np.random.choice([1,2,3,4,5,6,7,8,9],(3,4))
print(f"随机从数组中选取随机数,得到3行4列数组:\n{c}")

4.6shuffle把一个数进行随机排列

import numpy as np
b = np.arange(20).reshape(4,5)
print(b)
print("对数组进行随机排列")
np.random.shuffle(b)
print(b)

二维数组:将行重新随机排列,不改变列

三维数组:按块重新随机排序

4.7permutation

与shuffle功能一样

import numpy as np
print(np.arange(10))
print("随机排序后")
print(np.random.permutation(10))#10相当于range(10)

注:与shuffle不一样的是:随机排序后,permutation不改变原数组

4.8normal

normal生成正态分布数字,normal【平均值,方差,size(维度)】

4.9uniform均匀分布

np.random.uniform(1,10,10):1到10之间生成随机10个数

五.通用函数

一元通用函数

sqrt():返回平方根

exp():e的x次方

import numpy as np
a = np.arange(10)
print(a)
print("-----------")
print(np.sqrt(a))#每个元素的平方根
print("-------------")
print(np.exp(a))#每个元素的e的x次方

二元通用函数:两个数组求返回值

np.add(a,b)//对位相加

六.数学和统计方法

prod:所有元素的乘积

mean:数学平均

average:加权平均

std,var:标准差和方差

argmin:最小值的位置

cumsum:从0开始元素的累加

cumprod:从1开始元素的累积

percemtile:0-100百分位数

quantile:0-1分位数

6.1平均数,加权平均,中位数,众数

中位数:所有观察值高低排序找出中间值

加权平均:将各个数乘以相对于的权术,求和得到总体值,再除以总数

6.2一维数组

import numpy as np
a = np.array([0,1,4,2,5,6,8,4,10,3,23,44,56])
print(a)
print("-------------")
print(np.sum(a))
print("-------------")
print(np.prod(a))#乘法
print("-------------")
print(np.cumsum(a))
print("-------------")
print(np.cumprod(a))
print("-------------")
print(np.max(a))
print("-------------")
print(np.argmax(a))
print("-------------")
print(np.mean(a))#平均数
print("-------------")
print(np.median(a))#中位数
print("-------------")
print(np.average(a))#加权平均
print("-------------")
# 众数
counts = np.bincount(a)#统计非负整数个数,不统计浮点数
print(np.argmax(counts))#此方法不能用于二维数组

6.2二维数组

import numpy as np
array = np.array([[1,2,3],[4,5,6]])
print(array)
print("---------------------")
print(np.sum(array))
print("---------------------")
print(np.cumsum(array))#返回一维数组
print("---------------------")
print(np.cumprod(array))
print("---------------------")
print(np.max(array))
print("---------------------")
print(np.argmax(array))
print("---------------------")
print(np.mean(array))
print("---------------------")
print(np.median(array))
print("---------------------")
print(np.average(array))

6.3axis参数

axis=0:行

axis=1:列

import numpy as np
array = np.array([[1,2,3],[4,5,6]])
print(array)
print("---------------------")
# 按照行计算
print(np.sum(array,axis=0))#各行对位相加
# 按照列
print(np.sum(array,axis=1))

6.4数组中满足条件个数的计算

6.4.1将条件逻辑作为数组操作

import numpy as np
array = np.array([[1,2,3],[4,5,6]])
print(array)
print("---------------------")
# 大于3
print(array[array>3])
# 大于3的改为520.小于3的改为1314
print(np.where(array>3,520,1314))

6.4布尔数值

any:检查数组中是否至少有一个true

all:检查数组中是否每个值都是true

import numpy as np
array = np.array([True,True,False,True])
print(array)
print("---------------------")
print(array.any())#true
print(array.all())#false

6.5按值大小排序

一维数组:a.sort()

二维数组:np.sort(a)#默认按最后的轴排序(列)

​ np.sort(a,axis=0)#按照行排序(竖着排)

6.6从大到小的索引

一维数组

import numpy as np
a = np.array([16,2,7])
print(a)
print("--------------")
b = np.argsort(a)#升序,返回一组索引值
print(b)
print("--------------")
print(a[b])#数组升序
c = np.argsort(-a)#降序
print(c)
print("--------------")
print(a[c])

二维数组

import numpy as np
a = np.array([[1,4,2],[49,3,22]])
print(a)
b = np.argsort(a)#默认按最后的轴(列)排序
print("-----------")
print(b)

6.7根据键值的字典序进行排序

6.8唯一值和其他集合逻辑unique和in1d

unqiue:去重复

import numpy as np
a = np.array(["张三","赵四","王五","赵六","张三","赵武"])
print(np.unique(a))

in1d:检查一个数组中的值是否在另一个数组中

import numpy as np
a = np.array(["张三","赵四","王五","赵六","张三","赵武"])
print(np.in1d(a,["赵四","王五"]))
#[False  True  True False False False]

七.浅拷贝与深拷贝

浅拷贝

a = b:不能这样赋值,因为a和b互相影响,在内存里a变了b也会变化

a = b[:]:视图操作,会创建新的对象a,但是a的数据完全由b保管,他们两个数据变化一致

深拷贝

a = b.copy():复制,相当于新开辟了一个空间保存b(a改变不影响b)

八.数据类型与新建文件

数据类型--------------------新建文件·

csv,txt pd.to_csv

excel pd.to_excel

sql pd.to_sql

import pandas as pd
url='e:/pandas/a.xlsx'
# 二维数据表
data = pd.DataFrame({'序号':[1,2,3],'姓名':['张三','李四','王五']})
# 设置索引列
data.set_index('序号')
data.to_excel(url)
print("新建a文件成功")

8.1读取txt与csv文件

read_csv:默认逗号做空格符

read_table:默认制表符做空格符,如果需要改变需要指定sep=‘,’

data.head():默认显示前5行数据,第一行做表头(共6行)

data.dtypes():返回数据类型

表头默认第一行,如果没有表头,header=None,names设置每一列的列名作为表头

index_col:设置索引列

skiprows:设置跳过的行

encoding:设置文本编码

nrows:显示几行

将文件先读取后转换:

import pandas as pd
url = 'e:/SpringBoot.txt'
data = pd.read_csv(url)
# 将txt文件转换为csv文件
data.to_csv('e:/SpringBoot.csv')
print(data)

8.2读取sql文件

import pandas as pd
import pymysql
# 连接对象
connect = pymysql.connect(host="localhost",user="root",password="123456",database="stc")
# 读取文件
data = pd.read_sql("select * from student",con=connect)
print(data)

8.3读取与修改excel文件

import pandas as pd
url = 'e:/pandas/a.xlsx'
data = pd.read_excel(url,index_col='序号')
print(data)

九.数据结构

DataFrame(df):二维数据,df.index:索引列;df.columns:列名

Series:一维数据(一行或一列)

9.1Series

字典

import pandas as pd
# 用字典创建Series,以字典的键作索引
dic = {'姓名':'张三','性别':'男','年龄':20}
data = pd.Series(dic)
print(data)

多个列表

# 存放在多个列表
a = ['姓名','性别','年龄']
b = ['李四','男',30]
data = pd.Series(b,index=a)
print(data)

data.values:获取Series的值

data.sort_index():按照索引排序

data_sort_values(xxx):按照xxx排序

data.isnull():查看是否为空

data.notnull():判断是否不为空

9.2DataFrame

import pandas as pd
data = pd.DataFrame([[1,2,4],[6,4,5],[7,8,9]],columns=['a','b','c'])#columns设置列标签
print(data['a'][0])#a列0行
print(data.loc[0]['a'])#loc按照行列标签名称查询
print(data.iloc[0][0])#按照行列标签的位置查询
print(data[['a','b']])#查询a,b列数据

字典

import pandas as pd
# 字典创建表格
dic = {'姓名':['张三','赵丽','王五'],
       '性别':['男','女','男'],
       '年龄':[20,19,10]
       }
data = pd.DataFrame(dic)
print(data)
# 数据类型
print(data.dtypes)
# 列索引
print(data.columns)
# 索引
print(data.index)
# 查询某一列
print(data['姓名'])
# 查尊某一行数据
print(data.loc[0])
# 查询某一个数据
print(data.iloc[0][0])
# 查询多行
print(data.loc[0:3])

多个列表

import pandas as pd
a = pd.Series(['张三','李四','赵六'],index=[1,2,3],name='姓名')
b = pd.Series(['男','男','男'],index=[1,2,3],name='性别')
c = pd.Series([20,11,19],index=[1,2,3],name='年龄')
table = pd.DataFrame({a.name:a,b.name:b,c.name:c})
print(table)

data.head():查看前几行

data.tail():查看后几行

data.values:查看表的值

data.shape:查看表的形状

data.fillna():将空值替换为某个值

data.replace(a,b):将a替换为b

data.reset_index(drop=True):删除索引列

data.rest_index(drop=False):索引列会被还原为普通列

十.连接查询

10.1Merge(字段名)

import pandas as pd
import numpy as np
a = pd.DataFrame({'姓名':['张三','李四','王五','赵六'],'出手次数1':np.arange(4)})
b = pd.DataFrame({'姓名':['张三','李四','赵丽'],'出手次数2':[1,2,3]})
print(a)
print("---------------")
print(b)
# 连接,on表示连接的字段名,how表示连接的方式
#inner:内连接(默认);left:左连接;right:右连接;outer:外连接
c = pd.merge(a,b,on='姓名',how='inner')
print("---------------")
print(c)

right_index:将右表的index作为连接键

left_on:左表对齐的列

suffix后缀参数:给每个表的重复列名增加后缀

suffix=[‘_l’,‘_r’]:左表重复列名后加’_l‘,右表加’_r’

10.2join

a.join(b)

(建议使用merge)

10.3concat(轴)

np中使用concatenate

import numpy as np
arr = np.arange(9).reshape(3,3)
print(arr)
print("------------")
# 按行合并
arr1 = np.concatenate([arr,arr],axis=0)
print(arr1)
print("------------")
# 按列合并
arr2 = np.concatenate([arr,arr],axis=1)
print(arr2)

pd中使用concat

import pandas as pd
a1 = pd.Series(['A','B','C','D'],index=[1,2,3,4])
a2 = pd.Series(['D','E'],index=[5,6])
print(a1)
print("-----------------")
print(a2)
print("-----------------")
# 默认按行连接
a3 = pd.concat([a1,a2])
print(a3)

如果将axis=1

#axis=1时,生成DataFrame表格,列名为0和1(两张表拼接)
print(pd.concat([a1,a2],axis=1))

10.3.1首尾相接

1.相同字段的表首尾相接

#concat默认首尾相接

pd.concat([a,b]);

2.在相接时加上一个层次的key来识别数据源来自于哪张表

import pandas as pd
a1 = pd.Series(['A','B','C','D'],index=[1,2,3,4])
a2 = pd.Series(['D','E'],index=[5,6])
a3 = pd.concat([a1,a2],keys=['X','Y'])
print(a3)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nyVmSmXQ-1663477585896)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220905121426297.png)]

10.3.2横向表拼接

1.axis=1为行对齐

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-V4OnLFb3-1663477585898)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220905121820959.png)]

2.join参数

join=inner:得到两张表的交集

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-o9BWV6cZ-1663477585899)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220905122343033.png)]

join=outer:得到两张表的并集

3.join_axes

join_axes的参数可以指定根据哪个轴来对齐数据,保留指定表的轴

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-afLUdHci-1663477585900)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220905123239813.png)]

10.3.3append

默认按行追加(Series和DataFrame中的方法)

df1.append(df2)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-otYvrY5J-1663477585901)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220905123431313.png)]

10.3.4无视index的concat

如果两个表的index都没有实际含义,使用ignore_index的参数,置true,合并的两个表就是根据列字段对齐,然后合并,最后重新整理一个新的index

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-geAqJF5r-1663477585901)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220905124039226.png)]

10.3.5合并的同时增加区分数据组的键

1.可以直接用key参数实现

a3 = pd.concat([a1,a2],keys=[‘X’,‘Y’])

2、传入字典来增加分组键

pieces = {'X':a1,'Y':a2}
print(pd.concat(pieces))

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-btirKnvs-1663477585902)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220905124558427.png)]

10.3.6在dataframe中加入新的行

append方法,将参数ignore_index=True

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6GF6UykF-1663477585902)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220905125149225.png)]

10.3.7表格列字段不同的表合并

ignore_index=True

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EahVBDfV-1663477585903)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220905125627224.png)]

十一.填充数据

1.skiprows:跳过几行

usecols:和Excel一样,选定的列区域

2.数据.at:获取某个位置的值,数据.at[0,‘a’],相当于index=0,columns=‘a’

import pandas as pd
import datetime as dt

#累加月函数
def plusdd(dd, i):
   y = i // 12
   m = dd.month + i % 12
   if m != 12:
      y = y + m // 12
      m = m % 12
   return dt.date(y + dd.year, m, dd.day)


url = 'e:/pandas/b.xlsx'
# 设置跳过前几行,并取中间几列
data = pd.read_excel(url,skiprows=7,usecols='F:I',dtype={'序号':str,'姓名':str,'年龄':str})
# 起始日期
start = dt.date(2022,9,16)
#循环设置添加值
for i in data.index:
   data['序号'].at[i] = i+1
   data['年龄'].at[i] = 20 if i%2==0 else 19
   # 累加日
   data['日期'].at[i] = start+dt.timedelta(days=i)
   # 累加年
   # data['日期'].at[i] = dt.date(start.year+i,start.month,start.day)
   # 累加月
   data['日期'].at[i] =plusdd(start,i)
# 注:索引不可以直接修改
# 不使用新的索引,直接在原先的上修改
data.set_index('序号',inplace=True)
data.to_excel(url)
print(data)

十二.数据

12.1列与列之间的计算

import pandas as pd
url = "e:/pandas/d.xlsx"
data = pd.read_excel(url,index_col='序号')
# 计算销售金额
data['销售金额'] = data["单价"]*data["销售数量"]
# 单价涨价,苹果涨两元
data['涨价'] = data["商品名称"].apply(lambda x:2 if x == '苹果' else 0)
data["最终单价"] = data["单价"]+data["涨价"]
data["名称字数"] = data["商品名称"].apply(len)
print(data)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HkrJwUQO-1663477585903)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220906161404248.png)]

apply函数

import pandas as pd
import numpy as np
arr = [
    [1,2,3],
    [4,5,6],
    [7,8,9]
]
data = pd.DataFrame(arr,columns=list("xyz"),index=list("abc"))
# 将数据全部平方
data = data.apply(np.square)
# 对y,z列平方
data2 = data.apply(lambda m:np.square(m) if m.name in ['y','z'] else m)
# 对每行进行计算,axis设置为1轴
data3 = data.apply(lambda m:np.square(m) if m.name == 'a' else m,axis=1)
print(data)
print("-------------")
print(data2)
print("-------------")
print(data3)

计算间隔

import pandas as pd
url = "e:/pandas/e.xlsx"
data = pd.read_excel(url,index_col="序号")
gap = data['结束日期'] - data['开始日期']
data['间隔'] = gap.apply(lambda x:x.days)
print(data)

12.2数据排序

单个数据排序

import pandas as pd
url = "e:/pandas/f.xlsx"
data = pd.read_excel(url,index_col='序号')
# by:通过什么字段进行排序;ascending:True表示升序;inplace:True修改原始数据,False:data数据未修改,data2是排序后的结果
data2 = data.sort_values(by='语文',inplace=False,ascending=True)
print(data)
print("-----------")
print(data2)

多个数据排序

data2 = data.sort_values(by=['语文','数学'],inplace=False,ascending=[True,False])

按索引进行排序

import pandas as pd
url = "e:/pandas/f.xlsx"
data = pd.read_excel(url,index_col='序号')
data.sort_index(inplace=True)
print(data)

注:按行进行排序,axis=1(1轴)

12.3数据查询

import pandas as pd
url = "e:/pandas/f.xlsx"
data = pd.read_excel(url,index_col='序号')
data.sort_index(inplace=True)
# loc按照行列标签名查询
print(data.loc[1:3,'数学':'英语'])
print("-------------")
# 查询语文及格,数学不及格的人
print(data.loc[(data['语文']>=60)&(data['数学']<60)])
print("------------")
# 新增一列’称呼‘,如果为男则为’先生‘,否则为’女士‘
data.loc[data['性别']=='男','称呼'] = '先生'
data.loc[data['性别']=='女','称呼'] = '女士'
print(data)

12.4筛选

import pandas as pd
url = 'e:/pandas/f.xlsx'
data = pd.read_excel(url,index_col='序号')
print(data)
print("----------")
# 筛选性别为男
con = data['性别']=='男'
print(data[con])
print("----------")
# 性别为男并且语文及格的(条件为字符串)
con2 = "性别 == '男' and 语文>=60"
print(data.query(con2))
print("----------")
# 姓名为张三或赵丽
con3 = "姓名 in ['张三','赵丽']"
print(data.query(con3))

12.4.1文本筛选

startswith,contains

import pandas as pd
url = 'e:/pandas/f.xlsx'
data = pd.read_excel(url,index_col='序号')
print(data)
print("----------")
# startswith筛选开头
#筛选姓张的
con = data['姓名'].str.startswith('张')
print(data[con])
print("-------------")
# 筛选名字中含“丽”的,contains,case匹配敏感度,默认为true(大小写区分)
con2 = data['姓名'].str.contains('丽')
print(data[con2])

12.4.2附:获取某个日期之前/后

dataframe的truncate()可以截取某个日期之前/后的数据,或某个日期区间

注:使用前需要先排序,将日期设置为索引

12.4.3日期筛选

import pandas as pd
url = 'e:/pandas/f.xlsx'
# 将出生日期设置为日期格式
data = pd.read_excel(url,index_col='出生日期',parse_dates=['出生日期'])
print(data)
print("----------")
# 筛选2020年5月出生的
print(data['2020-05'].head())
print("----------")
# 将日期排序
data.sort_values('出生日期',inplace=True)
# 查询2022年以前出生的
print(data.truncate(after='2022').head())
print("----------")
# 获取指定时间区间2020年到2022年
print(data['2020':'2022'])

多条件筛选

注:此时的出生日期不能为索引

import pandas as pd
url = 'e:/pandas/f.xlsx'
# 将出生日期设置为日期格式
data = pd.read_excel(url,index_col='序号',parse_dates=['出生日期'])
print(data)
print("----------")
con = (
    '@data.出生日期.dt.year > 2020 and'
    '@data.出生日期.dt.year < 2021'
    'and 性别=="男"'
)
print(data.query(con))

12.5数据删除

drop函数

url = "e:/pandas/f.xlsx"
data = pd.read_excel(url,index_col="序号")
# 删除序号为2的数据
print(data.drop(2,inplace=True))
# 删除一行和5行
print(data.drop(labels=[1,5]))
# 删除语文列
print(data.drop('语文',axis=1))

12.6处理缺失值

删除缺失值

import pandas as pd
url = "e:/pandas/g.xlsx"
data = pd.read_excel(url,index_col="序号")
print(data)
print("------------")
# 删除所有包含空值的行
print(data.dropna())
print("------------")
#删除所有包含空值的列
print(data.dropna(axis=1))
print("------------")
# 每一行中至少保留5个非空值
print(data.dropna(thresh=5))
print("------------")
# 从指定的列中删除有空值的行
print(data.dropna(subset=['语文','数学']))

填充缺失值

# 将所有空值替换为‘a’
print(data.fillna('a'))
# 将语文列的空值替换为C,数学为M,英语为E
print("------------")
print(data.fillna({'语文':'C','数学':'M','英语':'E'}))

填充方式

ffill:用前面的值填充

print(data.fillna(method="ffill"))

bfill:用后面的值填充

print(data.fillna(method="bfill"))

pad:向后填充

backfill:向前填充

注:如果轴变了,axis=1,左右代表前后,limit限制填充个数

12.7数学统计函数

# 数学统计函数
print(data.describe())

数学统计函数表

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OumVHeAs-1663477585904)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220908145157696.png)]

12.8删除重复和提取重复

重点方法:drop_duplicates

​ duplicated

# 去重
print(data['姓名'].unique())
# 统计出现次数
print(data['姓名'].value_counts())
print("---------------")
# 删除重复值:drop_duplicates
# subset:用来指定特定的列
# keep:指定处理重复值的方法:first:保留第一次出现的值;false:删除所有重复值
print(data.drop_duplicates(subset=['姓名'],keep='first'))
# 姓名列是否有重复的行:duplicated:true表示重复
print(data['姓名'].duplicated())
print("---------------")
# 利用布尔值获得重复的行
c = data['姓名'].duplicated()
print(data[c])

12.9算数运算与数据对齐

1.处理空值,0替换空值

result = data['1店'].fillna(0)+data['2店'].fillna(0)
result2 = data['1店'].add(data['2店'],fill_value=0)

2.处理无穷大

import pandas as pd
url = "e:/pandas/j.xlsx"
data = pd.read_excel(url)
# 除0得到无穷大
result2 = data['1店'].div(data['2店'],fill_value=0)
print(result2)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bQK5KfOs-1663477585904)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220908161201800.png)]

将无穷大看作缺失值

import pandas as pd
url = "e:/pandas/j.xlsx"
data = pd.read_excel(url)
# 将无穷大看作缺失值
pd.options.mode.use_inf_as_na = True
# 除0得到无穷大
result2 = data['1店'].div(data['2店'],fill_value=0)
print(result2.fillna(0))

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wQDaiauJ-1663477585905)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220908161427235.png)]

12.10多层索引与多层索引计算

import pandas as pd
url = "e:/pandas/k.xlsx"
# 设置索引
data = pd.read_excel(url,index_col=[0,1])
# 有序索引中:取1班的数据,:表示所有列,slice(None)表示所有行
data2 = data.loc[(1,slice(None)),:]
# 无序索引,必须先按照索引排序
print(data2)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TBTVGFXP-1663477585905)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220908163315471.png)]

12.10.1行索引

import pandas as pd
# 数组创建多层索引
aa = pd.MultiIndex.from_arrays([['a','a','b','b'],[1,2,1,2]],names=['x','y'])
print(aa)
# 元组创建多层索引
bb = pd.MultiIndex.from_tuples([('a',1),('a',2),('b',1),('b',2)],names=['A','B'])
print(bb)
# 笛卡尔积创建多层索引
cc = pd.MultiIndex.from_product([['a','b'],[1,2]],names=['M','N'])
print(cc)

12.10.2列索引

# 行索引
index = pd.MultiIndex.from_product([[2021,2022],[5,6]],names=['年','月'])
# 列索引
columns = pd.MultiIndex.from_product([['香蕉','苹果'],['土豆','茄子']],names=['水果','蔬菜'])
data = pd.DataFrame(np.random.rand(4,4),index=index,columns=columns)
print(data)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kXmzo0Qx-1663477585906)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220908165318500.png)]

12.10.3分层索引计算

import pandas as pd
url = "e:/pandas/l.xlsx"
data = pd.read_excel(url,header=[0,1])
# 计算土豆和倭瓜的销量和毛利分别的和
result1 = data['土豆'] + data['倭瓜']
# 计算土豆和倭瓜的销量和
result2 = data[('土豆','销量')]+data[('倭瓜','销量')]
# 创建总计索引,得到销量和毛利分别的和
sum = data['土豆'] + data['倭瓜']
sum.columns = pd.MultiIndex.from_product([['合计'],sum.columns])
# 按列进行合并
data = pd.concat([data,sum],axis=1)
print(data)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-y5xZjYQO-1663477585906)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220908171223179.png)]

附:MultiIndex参数表

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SqGkO68f-1663477585907)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220908163216602.png)]

12.11数据替换

import pandas as pd
url = "e:/pandas/m.xlsx"
data = pd.read_excel(url)
# 替换数据
data['地区2'].replace('城八区','海淀区',inplace=True)
# 用字典替换多个值
dic = {'城八区':'CB','海淀区':'HD'}
data.replace(dic,inplace=True)
# 通过字符串修改
data['地区'] = data['地区'].str.replace('B','Q')
print(data)

12.12离散化和分箱

1.cut函数

pd.cut(x,bins,right=True,labels=None,retbins=False,precision=3

,include_lowest=False)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UROlUNNk-1663477585907)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220908182908082.png)]

year = [1992,1981,1990,1997,1987]
pack = [1980,1990,2000]
result = pd.cut(year,pack)
print(result)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Uy918Mc1-1663477585907)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220908184505309.png)]

# 获得每个数字对应的箱号。1980-1990:0;1990-2000:1
result2 = pd.cut(year,pack,labels=False)
print(result2)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jFIEqdi3-1663477585908)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220908184555882.png)]

2.qcut

import pandas as pd
year = [1992,1981,1990,1997,1987,1994,1992.1976]
# q指定所分箱子的数量
result = pd.qcut(year,q=4)
print(result)

12.13字符串操作

字符串:不可变的序列

import pandas as pd
url = "e:/pandas/n.xlsx"
data = pd.read_excel(url)
# 将单位度去掉,并修改类型,replace替换函数
print(data['温度'].str.replace('℃','').astype('int64'))
# cat,拼接函数
print(data['姓名'].str.cat(sep=','))
# split,分割函数,可以指定分割次数n;expand默认false,true表示返回一个数据框(二维表)
print(data['状态'].str.split('血'))
# partition,按照指定的字符分割(只分割第一次出现的字符),将该字符的左右均分隔开,总共分割为三列
print(data['状态'].str.partition('血'))
# get,获得第几列数据
print(data['状态'].str.get(1))
# slice,切片[m:n]
print(data['状态'].str.slice(0,3))
# slice_replace,切片筛选之后替换
print(data['状态'].str.slice_replace(1,3,'20'))
# join,用指定字符连接
print(data['状态'].str.join('a'))
#contains,字符串是否包含某个字符
print(data['状态'].str.contains('血'))
# startswith,是否以某个字符开头;endswith,是否以某个字符结尾
print(data['状态'].str.startswith('满'))
print(data['状态'].str.endswith('活'))
# repeat,将字符串重复
print(data['姓名'].str.repeat(3))
# pad,用指定字符补齐位数,fillchar表示补齐的字符,side表示在哪一边补齐,both表示两端补齐
print(data['姓名'].str.pad(5,fillchar='&',side='both'))
# zfill,用0从左边补齐位数
print(data['姓名'].str.zfill(10))
# encode,编码;decode,解码
# strip.去除指定的字符串
print(data['状态'].str.strip('血复活销毁'))

get_dummies:按指定字符分割,并统计和他相近的字符

print(data['地区'].str.get_dummies('国'))

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RtsxuaI1-1663477585908)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220910151353481.png)]

translate:将指定的字符转换

dic = str.maketrans({'血':'xue','活':'huo'})
print(data['状态'].str.translate(dic))

find:查找指定字符的第一次出现的位置,若没有则返回-1

print(data['日期'].astype('str').str.find("-"))

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OPtCuvv4-1663477585909)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220910152644999.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wQRckeR8-1663477585909)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220910152606213.png)]

12.14正则表达式

match:是否匹配

print(data['状态'].str.match('.{2}复'))

extract:分组

# '()'表示分组
print(data['日期'].astype('str').str.extract('\d{4}-(\d{2})-(\d{2})'))

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zWkBPehV-1663477585910)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220910153743698.png)]

replace:替换

# 将年月日颠倒
print(data['日期'].astype('str').str.replace('(\d+)-(\d+)-(\d+)',r'\3/\2/\1'))

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dU3diNVg-1663477585910)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220910154359695.png)]

12.15Excel文件的拆分与合并

1.将一个文件夹下的几张表合并为一张表

import pandas as pd
import os
url = "e:/pandas/project/"
table = pd.DataFrame();
# 获得project目录下的文件
for i in os.listdir(url):
     t = pd.read_excel(url+i)
     # 合并表,设定表头
     table = pd.concat([table,t],header=1)
print(table)

2.将一张表的多个sheet合并,None:将所有表作为数据文件

import pandas as pd
import os
url = "e:/pandas/e.xlsx"
data = pd.read_excel(url,None)
table = pd.DataFrame();
# 获取列表的字段名
col = list(data.keys())
for i in col:
    newData = data[i]
    table = pd.concat([table,newData])
print(table)

3.将一个表拆封成多个sheet

import pandas as pd
url = "e:/pandas/n.xlsx"
data = pd.read_excel(url)
# 将姓名作为分割列
col = list(data['姓名'])
# 将新数据写到哪
newData = pd.ExcelWriter('e:/pandas/n2.xlsx');
for i in col:
    data1 = data[data['姓名'] == i]
    data1.to_excel(newData,sheet_name=i)
newData.save()
newData.close()

将一张表拆分成多个表

import pandas as pd
url = "e:/pandas/n.xlsx"
data = pd.read_excel(url)
# 将姓名作为分割列
col = list(data['姓名'])
for i in col:
    data1 = data[data['姓名'] == i]
    data1.to_excel('e:/pandas/'+i+'.xlsx')

12.16分组与聚合

1.groupby基础部分

groupby():分组聚合(基于行)

# 按照城市,区分组,按照人数聚合,金额
data2 = data.groupby(['城市','区'])[['人数','金额']].sum()

agg:分组聚合(基于列)

dic = {'1月':'count','2月':sum,'3月':max}
data2 = data.groupby('店号').agg(dic)
print(data2)

2.分组对象和创建

isin():函数判断元素是否在该列表中

# 按照区是否在开发区,高新区中分组聚合
data2 = data.groupby(data..isin(['开发区','高新区']))[['人数','金额']].sum()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JGD4dKoS-1663477585911)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220912171820068.png)]

pipe:分组聚合

data2 = data.pipe(pd.DataFrame.groupby,'城市').sum()

12.17数据透视表

pivot_table()

# index:行标签,columns:添加下级分类,values:列表签,aggfunc:指定列上如何聚合,fillValue:填充缺失值,margin如果为true:添加行/列总和
data2 = pd.pivot_table(data,index=['城市','区'],values='人数',aggfunc=[sum,sum])

12.18vlookup

如何在pandas中实现excel的vlookup

(1)merge,loc实现

(2)删除drop再插入insert

import pandas as pd
url = "e:/pandas/p.xlsx"
data1 = pd.read_excel(url,sheet_name='花名册')
data2 = pd.read_excel(url,sheet_name='成绩单')
# 将两张表连接,以第一张表为基准,和第二张表的总分以及学号连接,按照左连接的方式以学号连接
result = pd.merge(data1,data2.loc[:,['学号','总分']],how='left',on='学号')
print(result)
# 将总分列插在学号之后
result2 = result['总分']
# 删除总分列
result=result.drop('总分',axis=1)
# 重新插入
result.insert(1,'总分',result2)
print(result)

12.19数据处理三板斧

1.map(单行单列)

import pandas as pd
url = "e:/pandas/g.xlsx"
data = pd.read_excel(url)
# map映射-字典
dic = {'男':'先生','女':'女士'}
data['性别']  = data['性别'].map(dic)
# map映射-函数
def rr(x):
    sex = '先生'if x== '男' else'女'
    return sex
data['性别'] = data['性别'].map(rr)
print(data)

2.apply:单行单列(多个数据)

import pandas as pd
url = "e:/pandas/g.xlsx"
data = pd.read_excel(url)
def modify(x,value):
    return x+value;
# 语文减3分
data['语文'] = data['语文'].apply(modify,args=(-3,))
print(data)

3.多行多列

data2 = data[['数学','语文','英语']].apply(sum,axis=0)

axis=0:按行相加,求汇总

12.20数据的转置,计算环与同比

1.转置

# 把数据进行转置:data.value.T,转置之后,行列互换
data2 = pd.DataFrame(data.values.T,index=data.columns,columns=data.index)

2.计算环比:上一列-下一列(a - a.shift())

注:先排序分组再计算

import pandas as pd
url = "e:/pandas/k.xlsx"
data = pd.read_excel(url)
# 排序
data['score2'] = data.分数.shift()
# 环比 = score - score2
cir = data['score2'] - data['分数']
data['环比'] = cir;
print(data)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7vi9gVhb-1663477585911)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220912194338171.png)]

3.同比

第二年 - 第一年

同比率:(第二年-第一年)/第一年

十三.matplotlib

bar函数--------------条形图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PR5z0nYx-1663477585911)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220914092532629.png)]

设置图例位置loc=

upper right
upper left
lower left
lower right
right
center left
center right
lower center
upper center
center

pie函数---------------饼图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4sENxYXu-1663477585912)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220914111912211.png)]

plot函数------------折线图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xcNtNk68-1663477585913)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220915141502893.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JLsSuCiF-1663477585913)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220915144011475.png)]

13.1柱状图

import pandas as pd
import matplotlib.pyplot as plt
url = "e:/pandas/r.xlsx"
# 设置中文字体,防止中午乱码font.sans-serif
plt.rcParams['font.sans-serif'] = ['SimHei']
# 设置负号axes.unicode_minus
plt.rcParams['axes.unicode_minus'] = False

data = pd.read_excel(url)
data.sort_values(by='第一年',inplace=True,ascending=False)

# 开始画图,x表示x轴,height表示条形的高度,label表示图例
plt.bar(x=data['姓名'],height=data['第一年'],label='第一年')

#设置标题,字号,粗体
plt.title("一年级学生第一年的成绩",fontsize=16,fontweight='bold')

# 设置行列标题
plt.xlabel('姓名')
plt.ylabel('第一年')

# 将x轴数字进行倾斜
# xticks设置或查询x轴刻度值
plt.xticks(data['姓名'],rotation=45)

# 设置y轴的范围
plt.ylim([-100,100])

# 显示图例,默认在右上角
plt.legend(loc="upper left")#设置在左上方

# 显示绘图
plt.show()

13.2条形图

import pandas as pd
import matplotlib.pyplot as plt
url = "e:/pandas/r.xlsx"
# 设置中文字体,防止中午乱码font.sans-serif
plt.rcParams['font.sans-serif'] = ['SimHei']

data = pd.read_excel(url)
data.sort_values(by='第一年',inplace=True,ascending=False)

# 画图,bottom表示条形图起始坐标(y轴起始坐标),width表示条形图长度,orientation表示垂直条还是水平条,alpha为透明度
plt.bar(x=0,bottom=data['姓名'],height=0.5,width=data['第一年'],color="green",orientation="horizontal",alpha=0.5)

# 设置行列标题
plt.xlabel("第一年")
plt.ylabel("姓名")

# 设置标题
plt.title("一年级学生的成绩",fontsize=16)

# 显示图像
plt.show()

13.3分组柱状图

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
url = "e:/pandas/r.xlsx"
data = pd.read_excel(url)
# 用黑体显示中文
plt.rcParams['font.sans-serif']= ['SimHei']
data.sort_values(by='第二年',inplace=True,ascending=False)
# 开始画图,bar
# x轴为姓名,第一个柱为第一年,红色显示,宽度为0.3
wid = 0.3
plt.bar(x=data.姓名,height=data.第一年,color="red",width=wid,label='第一年')#添加图例:第一年
# 第二个柱为第一年的柱下标加宽度
plt.bar(x=np.arange(len(data.姓名))+wid,height=data.第二年,color="blue",width=wid,label='第二年')

# 添加图例,默认右上角
plt.legend()

# 将底部轴文字斜体,对轴进行设置
plt.xticks(data['姓名'])
axis = plt.gca()#获取轴
axis.set_xticklabels(data['姓名'],rotation=45,ha="center")#从中心点旋转45度

# 将整个图进行操作
graph = plt.gcf()
graph.subplots_adjust(left=0.1,bottom=0.3)#距左边0.1,下边0.3
plt.show()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3XK2vcuM-1663477585913)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220914085148743.png)]

添加数据标签

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B0XJXTzY-1663477585914)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220914100138349.png)]

# 添加数据标签
for x,y1 in enumerate(data['第一年']):#enumerate枚举函数,添加索引,z为索引,y1为数据
    plt.text(x,y1/2,str(y1),fontsize=20,rotation=0,ha="center",va="center")#水平居中,垂直放在滑块的中间(高度的1/2)
for x,y2 in enumerate(data['第二年']):
    plt.text(x+wid,y2/2,str(y2),fontsize=20,rotation=0,ha="center",va="center")

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bwyo0DEo-1663477585915)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220914102601147.png)]

13.4叠加柱状图

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
url = "e:/pandas/r.xlsx"
data = pd.read_excel(url)

# 用黑体显示中文
plt.rcParams['font.sans-serif']= ['SimHei']

# 画图
plt.bar(np.arange(5),height=data['第一年'],color="red",label="第一年")
plt.bar(np.arange(5),height=data['第二年'],bottom=data['第一年'],color="green",label="第二年")#bottom实现叠加
plt.bar(np.arange(5),height=data['第三年'],bottom=data['第二年']+data['第一年'],color="blue",label="第三年")

# 设置x轴标签
plt.xticks(np.arange(5),data['姓名'])

# 设置图例,将默认三行设置为三列,向上居中
plt.legend(loc="upper center",ncol=3)

# 设置y轴刻度
plt.ylim([20,250])

# 添加网格线
#plt.grid()

# 添加数据标签
for x1,y1 in enumerate(data['第一年']):
    plt.text(x1,y1-10,str(y1),fontsize=16,ha="center")
for x2,y2 in enumerate(data['第二年']+data['第一年']):
    plt.text(x2,y2-10,str(y2),fontsize=16,ha="center")
for x3,y3 in enumerate(data['第三年']+data['第二年']+data['第一年']):
    plt.text(x3,y3-10,str(y3),fontsize=16,ha="center")
# 显示图像
plt.show()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Eo0ZXLHr-1663477585915)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220914105554632.png)]

13.5叠加条形图

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
url = "e:/pandas/r.xlsx"
data = pd.read_excel(url)

# 用黑体显示中文
plt.rcParams['font.sans-serif']= ['SimHei']

# 画图
plt.bar(x=0,bottom=data['姓名'],height=0.5,width=data['第一年'],label="第一年",color="red",orientation="horizontal")
plt.bar(x=data['第一年'],bottom=data['姓名'],height=0.5,width=data['第二年'],label="第二年",color="green",orientation="horizontal")
plt.bar(x=data['第二年']+data['第一年'],bottom=data['姓名'],height=0.5,width=data['第三年'],label="第三年",color="blue",orientation="horizontal")

# 添加数据标签,注:x和y的位置互换
for x1,y1 in enumerate(data['第一年']):
    plt.text(y1-10,x1,str(y1),fontsize=16,rotation=0,va="center",ha="center")
for x2,y2 in enumerate(data['第二年']+data['第一年']):
    plt.text(y2-10,x2,str(y2),fontsize=16,rotation=0,va="center",ha="center")
for x3,y3 in enumerate(data['第一年']+data['第二年']+data['第三年']):
    plt.text(y3-10,x3,str(y3),fontsize=16,rotation=0,va="center",ha="center")

# 显示绘图
plt.show()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IVXG3tZJ-1663477585916)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220914111533970.png)]

12.6饼图

import pandas as pd
import matplotlib.pyplot as plt
url = "e:/pandas/r2.xlsx"
data = pd.read_excel(url)

# 用黑体显示中文
plt.rcParams['font.sans-serif']= ['SimHei']

#画图,explode:逆时针设置块离开中心距离,autopct设置百分比,后面添加两个百分号,输出数据加百分号,若不加,则没有百分号,counterclock设置为false时,为顺时针,labeldistance为标签位置.默认1.1,缩小则可放进图中,radius为半径,pctdistance设置百分比位置,textprops设置文本,shadow设置为True时,显示阴影,可现实3d效果。
plt.pie(x=data['第一次'],labels=tuple(data['姓名']),explode=[0,0.2,0],colors=['r','g','b'],autopct="%.2f%%",counterclock=False,labeldistance=0.8,textprops={'fontsize':20,'color':'w'})

# 将饼图变成正圆
plt.axis("equal")

# 添加图例,bbox_to_anchor设置外边距,borderaxespad设置图例内边距
plt.legend(loc="upper right",fontsize=10,bbox_to_anchor=(1.1,1.05),borderaxespad=0.3,ncol=3)

# 保存图片,可通过dpi设置分辨率
plt.savefig(r"e:\pandas\饼图.jpg")

# 显示图像
plt.show()

12.7折线图

import pandas as pd
import matplotlib.pyplot as plt
url = "e:/pandas/r.xlsx"
data = pd.read_excel(url)

# 用黑体显示中文
plt.rcParams['font.sans-serif']= ['SimHei']

# 画图
plt.plot(data['姓名'],data['第一年'],color="r",marker="*",ms=10)#数据点为*,大小为10号
plt.plot(data['姓名'],data['第二年'],color="b",marker="o",ms=10)#数据点为*,大小为10号
plt.plot(data['姓名'],data['第三年'],color="g",marker="^",ms=10)#数据点为*,大小为10号

# 数据标签
for z in [data['第一年'],data['第二年'],data['第三年']]:
    for x,y in zip(data['姓名'],z):
        plt.text(x, y+1, str(y), va="center", ha="center", fontsize=10)
# 显示
plt.show()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nrPQCp3T-1663477585917)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220915144100486.png)]

12.8平均线

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
url = "e:/pandas/s.xlsx"
data = pd.read_excel(url)

plt.rcParams['font.sans-serif'] = ['SimHei']#设置中文

# 画图
plt.bar(data['班级'],data['销量'],color="g",label="销量")

# 显示图例
plt.legend()

#平均线
avg = np.mean(data['销量'])
plt.axhline(y=avg,color='b',linestyle=":")#画线

# 显示
plt.show()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eH7y0YCX-1663477585917)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220915144505436.png)]

补充:

# 线段
plt.axhline(y=0.5,xmin=0.1,xmax=0.6,c='g')
# 填充
plt.axhspan(1,1.2,facecolor='g',alpha=0.4)#y轴从1到1.2
plt.axvspan(1,1.2,facecolor='b',alpha=0.5)#x轴从1到1.2

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0E8f8lTU-1663477585918)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220916082415452.png)]

设置x,y轴刻度

plt.axis([-1,2,1,4])#x[-1,2],y[1,4]

12.9画布以及子图

创建画布

import matplotlib.pyplot as plt
# 创建画布
#num显示画布名称,figsize显示画布大小(长宽),dpi设置分辨率,facecolor设置背景色
back = plt.figure(num="信息",dpi=200,facecolor='g')

# 创建子图
one = back.add_subplot(1,2,1)#一行两列第一个图
two = back.add_subplot(1,2,2)

# 显示
plt.show()

创建子图

import matplotlib.pyplot as plt
import pandas as pd
url = "e:/pandas/r.xlsx"
data = pd.read_excel(url)

plt.rcParams['font.sans-serif'] = ['SimHei']

# 创建画布
back = plt.figure()

# 创建子图
one = back.add_subplot(2,2,1)#两行两列第一个图
two = back.add_subplot(2,2,2)
three = back.add_subplot(2,2,3)
# 在第三个图上创建一个折线图
plt.plot(data['姓名'],data['第一年'],color="g",marker="o",label="第一年")
four = back.add_subplot(2,2,4)
# 在第四个图上创建一个条形图
plt.bar(data['姓名'],data['第一年'],label="第一年",color="b",alpha=0.6)

# 显示
plt.show()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5Q9rkNt5-1663477585918)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220915145821884.png)]

方法二

# 创建多个子图
img,back = plt.subplots(2,2)#布,图

one = back[0,0]
two = back[0,1]
three = back[1,0]
four = back[1,1]

one.bar(data['姓名'],data['第一年'],label="第一年",color="g")

four.pie(x=data['第二年'],labels=tuple(data['姓名']))

# 显示
plt.show()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZoXLVfR8-1663477585919)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220915151231228.png)]

创建子区域

import matplotlib.pyplot as plt
import pandas as pd
url = "e:/pandas/r.xlsx"
data = pd.read_excel(url)

plt.rcParams['font.sans-serif'] = ['SimHei']

# 画布
back = plt.figure()

# 创建区域
left,bottom,width,height = 0.1,0.1,0.8,0.8
one = back.add_axes([left,bottom,width,height])#添加轴

# 画图
one.bar(data['姓名'],data['第一年'])
one.set_title('第一年数据')

# 创建子区域
left,bottom,width,height = 0.65,0.6,0.25,0.25
two = back.add_axes([left,bottom,width,height])

# 画图
two.pie(x=data['第二年'],labels=tuple(data['姓名']))

# 显示
plt.show()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qaLSzJiA-1663477585919)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220915152402878.png)]

调整子图边框与间距

import matplotlib.pyplot as plt
img,back = plt.subplots(2,2)

# 调整子图间距,wspace是子图的宽,hspace是子图的高
img.subplots_adjust(wspace=0.5,hspace=0.3,left=0.125,right=0.9,bottom=0.1)

#或者
img.tight_layout()

plt.show()

12.10组合图

import pandas as pd
import matplotlib.pyplot as plt
url = "e:/pandas/r.xlsx"
data = pd.read_excel(url)

plt.rcParams['font.sans-serif'] = ['SimHei']

# 创建画布
back = plt.figure();

# 创建图
one = back.add_subplot(1,1,1)
one.bar(data['姓名'],data['第一年'],label='第一年',color='g')

#开启图例
plt.legend(loc="upper left")

# 设置y刻度
plt.ylim([0,100])

# 设置图二
two = one.twinx()
two.plot(data['姓名'],data['第二年'],color="r",label="第二年")

# 添加标签
for x,y in zip(data['姓名'],data['第二年']):
    plt.text(x,y+1,str(y),fontsize=10)

plt.legend(loc="upper right")

# 显示
plt.show()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f6de75yW-1663477585920)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220915162522150.png)]

设置百分比

import matplotlib.ticker as ticker
# 设置百分比
per = ticker.PercentFormatter(1,2)#最大为100%,保留两位小数
two.yaxis.set_major_formatter(per)
two.set_ylim([0,1])

# 添加标签
for x,y in zip(data['姓名'],data['第二年']):
    plt.text(x,y+1,str(round(y*100,2)),fontsize=10)

12.11坐标轴上的日期格式

import pandas as pd
import matplotlib.pyplot as plt
url = "e:/pandas/t.xlsx"
data = pd.read_excel(url)

plt.rcParams['font.sans-serif'] = ['SimHei']

#修改日期格式strftime
date = [d.strftime('%m-%d') for d in data['日期']]

plt.plot(date,data['销量'],label='销量')

plt.xticks(date,rotation=45)

plt.show()

12.12散点图

scatter函数-----------散点图

import pandas as pd
import matplotlib.pyplot as plt
url = "e:/pandas/u.xlsx"
data = pd.read_excel(url)

plt.rcParams['font.sans-serif'] = ['SimHei']

# s表示散点的大小,设置为身高,表示身高越大,s的点越大,c设置点的颜色
plt.scatter(data['身高'],data['体重'],s=data['身高'],c=data['身高'],marker="x")# 颜色由身高决定
#设置颜色
plt.colorbar()

plt.show()

12.13直方图

hist函数---------直方图

import pandas as pd
import matplotlib.pyplot as plt
url = "e:/pandas/v.xlsx"
data = pd.read_excel(url)

plt.rcParams['font.sans-serif'] = ['SimHei']

# 绘制直方图,bins组数
plt.hist(data['身高'],bins=30,facecolor="g",edgecolor="w")

plt.show()

12.14坐标轴

import matplotlib.pyplot as plt
img,back = plt.subplots(1,1)

# 设置坐标轴的颜色,none表示不显示坐标轴
back.spines['left'].set_color('none')
back.spines['bottom'].set_color('none')
back.spines['right'].set_color('none')
back.spines['top'].set_color('none')

# 翻转x,y的刻度
plt.gca().invert_yaxis()
plt.gca().invert_xaxis()

# 刻度消失
plt.xticks([])
plt.yticks([])

# 
plt.show()
# 将x轴的第二个刻度单独设置
plt.gca().get_xticklabels()[1].set(c='r',fontsize=30)
#设置x,y的区间
plt.gca().set_xlim([0,10])
plt.gca().set_ylim([0,5])
# 设置下限
plt.gca().set_ylim(bottom=5)
plt.gca().set_xlim(left=5)

12.15叠加区域图

import pandas as pd
import matplotlib.pyplot as plt

url = "e:/pandas/r.xlsx"
data = pd.read_excel(url)

plt.rcParams['font.sans-serif'] = ['SimHei']

plt.plot(data['姓名'],data['第一年'])
plt.plot(data['姓名'],data['第三年'])

# 绘制覆盖区域,下限是0,上限是data['第一年']
plt.fill_between(data['姓名'],0,data['第一年'],facecolor='r',alpha=0.6)
plt.fill_between(data['姓名'],data['第一年'],data['第三年'],facecolor='b',alpha=0.6)

plt.show()

区域的高亮显示

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(30)
y = np.random.rand(30)

plt.plot(x,y,color='g')

# 高亮显示
list = [[1,6],[10,15],[20,25],[26,28]]
for i in list:
    plt.fill_between(x[i[0]:i[1]],0,1,facecolor="g",alpha=0.6)

plt.show()

12.16极坐标

polar函数---------圆盘

import numpy as np
import matplotlib.pyplot as plt	
#极角,极径,ro表示红色的o标志
plt.polar(np.pi*0.25,20,"ro")
plt.ylim([0,100])
plt.show()

雷达图

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
url = "e:/pandas/z.xlsx"
data = pd.read_excel(url,index_col='姓名')

plt.rcParams['font.sans-serif'] = ['SimHei']

# 获得科目以及两个人的分数(首尾分数要相等)
one = "姓名=='A01'"
two = "姓名=='A02'"
a = data.query(one)['分数']
a = np.concatenate((a,[a[0]]))
b = data.query(two)['分数']
b = np.concatenate((b,[b[0]]))
c = data.query(one)['课程']
c = np.concatenate((c,[c[0]]))
print(a)

# 设置角度,linspace设置一维等差数列。endpoint设置为false时,不包含末尾值,len表示个数
angle = np.linspace(0,2*np.pi,len(a)-1,endpoint=False)
angle = np.concatenate((angle,[angle[0]]))
print(angle)

# 画图
back = plt.figure()
img = back.add_subplot(111,polar=True)#绘制圆盘

# 样式
plt.style.use("ggplot")

# 添加数据点,可以绘制折线图,o-可连接点
plt.plot(angle,a,"o-",label="A01同学",linewidth=2)
plt.plot(angle,b,"o-",label="A02同学",linewidth=2)

# 填充
plt.fill(angle,a,'b',alpha=0.25)
plt.fill(angle,b,'g',alpha=0.25)

# 标签
img.set_thetagrids(angle*180/np.pi,c)

# 显示图例
plt.legend()

plt.show()

补:创建子图标签

import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimHei']

back = plt.figure()

one = back.add_subplot(221)
two = back.add_subplot(222)
three = back.add_subplot(223)
four = back.add_subplot(224)

# 设置图上的标题
plt.suptitle('子图',fontsize=20,color='r')

# 设置标签,pad设置框的大小
dic = dict(facecolor='yellow',pad=5,alpha=0.2)
plt.xlabel('子图四',bbox=dic)

plt.show()

12.17交叉及填充

import matplotlib.pyplot as plt
import numpy as np
x = np.arange(0.0,2,0.01)
y1 = np.sin(2*np.pi*x)
y2 = 1.2*np.sin(4*np.pi*x)

img,back = plt.subplots()
back.plot(x,y1,x,y2,color='black')

# 交叉填充
back.fill_between(x,y1,y2,where=y2>y1,facecolor='g')#当y2>y2时
back.fill_between(x,y1,y2,where=y2<=y1,facecolor='b')

plt.show()

12.18文本注释

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-J0GVmQ3R-1663477585920)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220916084810254.png)]

import matplotlib.pyplot as plt
plt.plot(['A','B','C'],[5,3,2],'ro-')

dic = dict(facecolor='g',shrink=0.1)#shrink越大,箭头尾巴越短
plt.annotate('aaa',xy=('B',3),xytext=('B',2.5),arrowprops=dic)#xy设置点的位置。xytext设置文本位置

plt.show()
# 设置边框
border=dict(boxstyle='sawtooth',fc='0.8',ec='r')#fc:facecolor设置北京灰度,ec设置边框颜色
plt.text('B',3,'aaa',bbox=border,size=20)
#设置箭头
dic = dict(arrowstyle="->",connectionstyle='angle')
plt.annotate('aaa',xy=('B',3),xytext=('C',5),arrowprops=dic)

12.19瀑布图

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
url = "e:/pandas/z2.xlsx"
data = pd.read_excel(url)

plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False;

# 制作瀑布图
list = np.arange(len(data['金额']),dtype=np.float64)# 拿到下标
dis = 0;#下面的距离
for i in data['金额'].index:
    x = list[i]
    y = data.金额[i]
    if y >=0 :
        盈利 = plt.bar(x,y, 0.8,align='center',bottom=dis,label='盈利',color='g')
    else:
        亏损 = plt.bar(x,y, 0.8,align='center',bottom=dis,label='亏损',color='r')
    dis+=y;

# 绘制网格线
plt.gca().yaxis.grid(True,linestyle='--',color='grey',alpha=0.25)

# x轴日期
date = [d.strftime('%m-%d') for d in data['日期']]
plt.xticks(np.arange(len(data['金额'])),date,rotation=45)

plt.show()

12.20树状图

安装模块squarify

import squarify
import matplotlib.pyplot as plt
import pandas as pd
url = "e:/pandas/z3.xlsx"
data = pd.read_excel(url)

plt.rcParams['font.sans-serif'] = ['SimHei']

# 绘制
colors = ['r','b','g','c','m','y']# 颜色
img = squarify.plot(sizes=data['销售数量'],label=data['名称'],color=colors,value=data['销售数量'],edgecolor='white',linewidth=3)#sizes关键字(决定方块大小)。label标签名称,value代表标签值

# 去掉坐标轴
plt.axis('off')

# 标题
img.set_title('销售情况')
plt.show()

12.21玫瑰图

import numpy as np
import squarify
import matplotlib.pyplot as plt
import pandas as pd
url = "e:/pandas/z4.xlsx"
data = pd.read_excel(url)

plt.rcParams['font.sans-serif'] = ['SimHei']

colors=['r','g','b','c','m','y','k','yellow','purple','pink','grey','orange','r','g','b','c','m','y','k','yellow']
angle=np.linspace(0,2*np.pi,len(data['业绩']),endpoint=False)

img = plt.axes(polar=True)
img.set_theta_zero_location('N')#设置方向

grade = np.concatenate((data['业绩'],[data['业绩'][0]]))
angle = np.concatenate((angle,[angle[0]]))
name =  np.concatenate((data['姓名'],[data['姓名'][0]]))

# 绘制
plt.bar(angle,grade,width=0.3,color=colors)
# 挖孔
plt.bar(angle,height=100,width=0.3,color='white')

# 关闭轴
plt.gca().set_axis_off()

# 添加数据标签
for angle,grade,name in zip(angle,grade,name):
    plt.text(angle+0.1,grade+40,str(name))

plt.show()
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值