前纲
使用Python做数据分析,主要需要掌握:
Pandas(数据分析,清洗,预处理),matplotlib(可视化)以及seaborn(可视化)
数据读取代码
导入库:
import pandas as pd
导入数据:
df=pd.read_excel(r'...xlsx')
df.head()#仅用于浏览前5行数据
观看数据信息(非空值计数,数据类型):
df.info()
数据描述统计(非空值计数,平均值,标准差,最小值,分位数值):
df.describe()
数据排序代码
数据排序:
df.sort_values(by='需排序的数据表头',inplace=True/False)#默认升序True
df#此时是另起一列给出排序后的结果,并非在原先修改
自定义排序(按列A升序,列B降序,等等):
df.sort_values(by=['列A','列B',...],ascending=[True,False,...],inplace=True)
df
数据过滤代码
数据过滤(&与,条件确认用==,|或【与&用在同一处】):
df[(df['列A']=='单元值(定类)')&(df['列B']>单元值(定量))&...]
df[df['定类列'].isin(['值A','值B','值C','值D','值E'])]#从定类列中筛选出值A到E来
数据拆分代码
需要拆分的数据类型中有明确的“拆分符”:
df_split=df['列A'].str.split(pat='拆分符',expand=True)
#拆分符号,如该数据拆分符为“-”:福建-福州-福清
df['省份']=df_split.iloc[:,0]
df['市区']=df_split.iloc[:,1]
df['乡县']=df_split.iloc[:,2]
df
统计运算代码
计数
重复计数:
df['列名'].count()
非重复计数:
len(df['列名'].unique())#多用于定类数据确定“种类”
groupby区分计数:
df.groupby(['列A'])['列B'].count().reset_index()#将B按照A区分计数
求和
求和:
df['列名'].sum()
数据作图代码
饼图
#前提
import matplotlib.pyplot as plt
import matplotlib.style as psl
plt.rcParams['font.sans-serif']=['SimHei'] #正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #正常显示负号
psl.use('ggplot')
df_QY=df.groupby(['列A'])['列B'].count().reset_index()#所使用的数据是用列A区分的列B值
#饼图代码
#值定义
labels = df_QY['列A'].tolist()#定义标签文本
explode = [0.05,0.05,0,0,0,0] # 用于突出显示数据,表示前两段突出饼图半径5%
#绘制饼图
df_QY['列B'].plot(kind='pie',figsize=(9,6),#宽9英寸、高6英寸
autopct='%.1f%%',#保留一位小数并显示百分比
labels=labels,
startangle=260, #初始角度
explode=explode, # 突出显示数据
pctdistance=0.87, # 设置百分比标签与圆心的距离
textprops = {'fontsize':12, 'color':'k'}, # 标签字体大小设置为12,颜色设置为黑色
)
plt.title("饼图标题")
plt.show()
箱线图
#前提
import matplotlib.pyplot as plt
import matplotlib.style as psl
plt.rcParams['font.sans-serif']=['SimHei'] #正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #正常显示负号
psl.use('ggplot')
plt.title('箱线图标题')
df_XB=...#过滤和筛选过的数据
#箱线图
plt.boxplot(x=[df_XB['列名1'], df_XB['列名2'],...],#指定绘制箱线图的数据(定量)
whis=1.5, #指定1.5倍的四分位数差(用于分析异常值,因此定义为1会更严格,为2会更宽松,一般是1.5)
widths=0.3, #指定箱线图中箱子的宽度为0.3
showmeans=True, #显示均值
#patch_artist=True, #填充箱子颜色
#boxprops={'facecolor':'RoyalBlue'},#指定箱子的填充色为宝蓝色
flierprops={'markerfacecolor':'red','markeredgecolor':'red','markersize':3}, #指定异常值的填充色、边框色和大小
medianprops={'marker':'h','markerfacecolor':'black','markersize':8}, #指定中位数的标记符号(六边形)和颜色,大小
meanprops={'linestyle':'--','color':'orange','linewidth':2}, #指定均值点的标记符号(虚线)、填充色和大小
labels=['箱线图标签']
)
plt.show()
折线图
#前提,使用seaborn
import seaborn as sns
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei'] #正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #正常显示负号
plt.figure(figsize=(10,6))#设置图表大小
#使用Seaborn绘制折线图
sns.lineplot(data=df, x='列A', y='列B', color='blue')#列A通常是时间序列数据,列B通常是定量数据
#设置图表标题和轴标签
plt.title('折线图标题')
plt.xlabel('X轴标题')
plt.ylabel('Y轴标题')
#显示图形
plt.show()
词云图【wordcloud库】
from wordcloud import WordCloud
import matplotlib.pyplot as plt
#列A种类列表
A_categories = df['列A'].tolist()
#使用字典统计商品类别数量
category_counts = dict()
for category in A_categories:
if category in category_counts:
category_counts[category] += 1
else:
category_counts[category] = 1
#创建词云对象
wordcloud=WordCloud(font_path='simhei.ttf', background_color='white').generate_from_frequencies(category_counts)
#使用matplotlib绘制词云图
plt.figure(figsize=(9, 6))
plt.imshow(wordcloud, interpolation='bilinear')
plt.axis("off")
plt.show()
PDF内容抓取汇总至excel代码
需要用到PyPDF2
#前提
import re
import pandas as pd
import PyPDF2
#打开PDF
with open(r'系统路径.pdf', 'rb') as file:
reader = PyPDF2.PdfFileReader(file)
num_pages = reader.numPages
#通过每一页提取信息
info = []
for page_num in range(num_pages):
page = reader.getPage(page_num)
text = page.extractText()
例如合同其中一页面格式如此:
接续上面的代码:
# 使用正则表达式匹配所需信息
#“\s*(.*)', text”表示匹配空白字符后跟任意字符直到换行,根据合同格式不同有不同的正则匹配
HT_No = re.findall(r'合同编号:\s*(.*)', text)
name1 = re.findall(r'甲方:\s*(.*)', text)
name2 = re.findall(r'乙方:\s*(.*)', text)
catege = re.findall(r'品名:\s*(.*)', text)
weight = re.findall(r'采购数量(斤):\s*(.*)', text)
price = re.findall(r'采购单价(元 /斤):\s*(.*)', text)
price_sum = re.findall(r'总价(元):\s*(.*)', text)
# 将信息添加到列表中,其中[0]表示值,else后接空格表示空值,表示将字典添加到info列表中,有值则使用,否则为空字符串。
info.append({'合同编号': HT_No[0] if HT_No else '',
'甲方': name1[0] if name1 else '',
'乙方': name2[0] if name2 else '',
'品名': catege[0] if catege else '',
'采购数量': weight[0] if weight else '',
'采购单价': price[0] if price else '',
'总价': price_sum[0] if price_sum else ''}
)
# 将信息保存为Excel文件
df = pd.DataFrame(info)
df.to_excel(r'系统路径.xlsx', index=False)
一键完整探索性数据分析报告代码
#使用【pandas_profiling库】,三行代码即可生成一份具有交互式效果的HTML报告
df=pd.read_excel/csv(r'系统路径')
from pandas_profiling import ProfileReport
profile = ProfileReport(df,title='报告标题')
profile.to_file(r'自定义路径输出报告.html')
#可得到①数据集的基本信息②数据类型的分布情况③散点图相关性分析可视化④Spearman,Pearson矩阵相关性色阶图⑤缺失值数据可视化⑥样本信息展示,可用于标记重复行(duplicate row)
自定义图表数据格式代码
基础自定义
import pandas as pd
#这里便默认加载了一个数据df
#高亮显示
df.style.highlight_max(color='yellow')#高亮显示最大值
df.style.highlight_min(color='gray')#高亮显示最小值
df.style.highlight_null(null_color='red')#高亮显示空值
#隐藏列A/行A
df.style.hide_columns/index(['A'])
#链式调用(示例)
df.style.highlight_max().highlight_min(color='gray').highlight_null(null_color='blue')
#自定义数据类型
df.style.format({'列名1':'{:.0f}','列名2':'{:.2%}'},na_rep='空值')#对列1数据保留整数部分,对列2数据保留两位小数并转化为百分比,将数据中的空值替换为字符“空值”
色阶
#导入Seaborn库
import seaborn as sns
cmp=sns.light_palette('blue',as_cmap=True)#蓝色调色板
therm=df.iloc[:,0:n].style.background_gradient(cmap=cmp)#选择前n列所有行进行色阶调色,数值越大,颜色越深
数据条
df.style.bar(['列1','列2',...], align='mid', color=['#d65f5f','#5fba7d'])
#为各指定列添加在单元格中间对齐的条形图,左颜色代表+,右颜色代表-
http://www.yini.org/liuyan/rgbcolor.htmRGB颜色表
网页静态表格数据抓取代码
read_html
import pandas as pd
import requests
url_str = ' 网址'
dfs = [pd.read_html(requests.get(url_str + str(i + 1)).content)[0] for i in range(n)]
#上述dfs内进行循环遍历的操作用于爬取该网址更多页面的内容,通常是由于网址后缀界面更改同时更改数字即可使用该遍历,如“新浪财经”
df = pd.concat(dfs, ignore_index=True)
df.to_excel('系统路径.xlsx', index=False)
数据库存储代码
pymysql导入数据库
import pymysql
# 建立数据库连接
con = pymysql.connect(host='127.0.0.1', user='root', password='123456', db='demo', port=3306)
cursor = con.cursor()
# 创建表
cursor.execute('create table if not exists 表名(列A char(10) primary key, 列B int(10), 列C float)')
# 插入数据语句
query = "insert into 表名(列A,列B,列C) values (%s,%s,%s)"
# 迭代读取每行数据并插入
for r in range(len(df)):
values = (df.iloc[r,0], df.iloc[r,1], df.iloc[r,2])
cursor.execute(query, values)
# 提交更改,关闭游标和连接
con.commit()
cursor.close()
con.close()
read_sql数据库查询
import pymysql
import pandas as pd
# 建立数据库连接
con = pymysql.connect(host='127.0.0.1', user='root', password='123456', db='demo', port=3306)
# 执行SQL查询
sql = "..." # 这里填写SQL查询语句,语句和SQL内部一致
df_sql = pd.read_sql(sql, con)
df_sql.head()
简易用户画像分析代码
数据预处理
#数据导入
import pandas as pd
df=pd.read_excel(r'...')
#预处理
#查看数据类型,准备预处理
df.dtypes
#转换数据类型
df['列A']=df['列A'].astype(str)#数值转字符
df['列B']=df['列B'].str[n:].astype(float)#字符转数值,需要的数值在第n个字符后面
df['列C']=pd.to_datetime(df['列C'],format='%Y年%m月%d日')#字符转日期
#检测并删除重复值
if df.duplicated().any():
df = df.drop_duplicates()
#判断各列缺失值比例,缺失值大于30%的数据列不采用
ratio = df.isnull().sum(axis=0) / df.shape[0]
drop_cols = ratio[ratio > 0.3].index
if len(drop_cols) > 0:
print(f"删除缺失值比例大于30%的列:{drop_cols}")
df.drop(columns=drop_cols, inplace=True)
#删除列后仍有缺失值,直接删除所有带有缺失值的行
df.dropna(how='any', inplace=True)
#若行数据宝贵,可以采取这样的策略进行缺失值填充,mode是众数填充,mean是平均数填充
df.fillna(value={'列A': df['列A'].mode()[0], '列B': df['列B'].mean()}, inplace=True)
df.isnull().sum(axis=0)#最后检查是否仍然存在缺失值
关系可视化,研究“特征”与要求数据的关系
import pandas as pd
import matplotlib.pyplot as plt
plt.rcParams["font.sans-serif"] = 'SimHei' #中文乱码问题
plt.rcParams['axes.unicode_minus'] = False #负号无法显示
#例:要研究特征之间的量和对比
ft_union=df.groupby('列A')['列B'].sum()#一般列A是特征,列B是需求的定量数据,例如金额,订单数等等
ft_union.plot.bar()
plt.xticks(rotation=0)#若表头过长也可适当增加旋转角度
#定量数据但需要划分范围类群作为特征
sp_cut=pd.qcut(df['列C'],5)#对定量数据的列C按顺序等量分成五种定类区间
quan_cut=pd.cut(df['列B'],bins=[0,500,1000,1500,2000,2500,3000,...])#区间内不等量,用于观察定量数据其各量级的质量