文章目录
python数据挖掘一、数据挖掘基础环境安装与使用1.1 库的安装1.2 Jupyter Notebook使用1.2.1 Jupyter Notebook介绍1.2.2 为什么使用Jupyter Notebook?1.2.3 Jupyter Notebook的使用-helloworld二、Matplotlib2.1 Matplotlib2.1.1 什么是Matplotlib - 画二维图表的python库2.1.2 为什么要学习Matplotlib - 画图2.1.3 实现一个简单的Matplotlib画图2.1.4 拓展知识点:Matplotlib三层结构2.2 折线图(plot)与基础绘图功能2.2.1 折线图绘制与保存图片2.2.2完善原始折线图(辅助显示层)2.2.3多个坐标系显示-plt.subplots(面向对象的画图方法)2.2.4 折线图绘制函数图像2.3 散点图(scatter)2.4 柱状图(bar)2.5 直方图(histogram)2.5.1 直方图介绍2.5.2 直方图与柱状图的对比2.5.3直方图绘制2.6饼图三:Numpy介绍ndarraynumpy与list对比属性方法3.1基本操作3.1.1ndarray形状和类型3.1.2生成数组3.1.3索引切片3.1.4形状改变3.1.5类型修改3.1.6数组去重3.2ndarray运算3.2.1逻辑运算3.2.2统计运算3.2.3数组运算3.2.4数组合并分割四:Pandas4.0基本介绍4.1DataFrame4.1.0DataFrame结构4.1.1构造dataframe 利用**DataFrame**函数4.1.2常用操作(设置索引)4.1.3 MultiIndex与Panel4.1.4 Series4.2基本数据操作(很重要的一点是布尔值索引)4.2.1索引操作(bool索引见4.2.4)4.2.2赋值操作4.2.3排序4.2.4数学运算 布尔值索引4.2.5统计运算4.3画图pandas.DataFrame.plot4.4文件读取写入4.4.1 CSV文件4.4.2HDF5文件4.4.3 JSON文件4.5高级处理**4.5.1缺失值(标记值)处理**4.5.2 离散化4.5.3合并4.5.4交叉表与透视表4.5.6分组与聚合五:案例python数据挖掘
主要参考资料:
API reference — pandas 1.4.1 documentation ()
哔哩哔哩网课
走在小路上 笔记
下载markdown笔记(无需积分)
一、数据挖掘基础环境安装与使用
1.1 库的安装
pip install
集合到requirements.txt文件中集成安装
matplotlib==2.2.2numpy==1.14.2pandas==0.20.3TA-Lib==0.4.16 技术指标库tables==3.4.2 hdf5jupyter==1.0.0 数据分析与展示的平台
pip install -r requirments.txt
1.2 Jupyter Notebook使用
1.2.1 Jupyter Notebook介绍
web版的ipython名字缘由ju - Juliapy - Python
ter - R
Jupiter 木星 宙斯编程、写文档、记笔记、展示文件是.ipynb
1.2.2 为什么使用Jupyter Notebook?
画图方面的优势数据展示方面的优势1.2.3 Jupyter Notebook的使用-helloworld
界面启动、创建文件
在终端输入jupyter notebook / ipython notebook
注意可以是pycharm中的终端,也可以直接是windows终端,不过要将路径调整到你的项目路径
如图
然后点击网址即可
快速上手的方法:
快捷键
运行代码 shift + enter
cell操作
cell:一对In Out会话被视作一个代码单元,称为cell
编辑模式:enter 鼠标直接点
命令模式:esc 鼠标在本单元格之外点一下
快捷键操作
执行代码,并跳转到下一单元:shift + Enter
执行本单元代码,留在本单元:ctrl+Enter
命令模式:
Y:cell切换到code模式
M:cell切换到markdown模式
A:在当前cell的上面添加cell
B:在当前cell的下面添加cell
双击D:删除当前cell
编辑模式:
多光标操作:Ctrl键点击鼠标(Mac:CMD+点击鼠标)
回退:Ctrl+Z(Mac:CMD+Z)
补全代码:变量、方法后跟Tab键
为一行或多行代码添加/取消注释:Ctrl+/(Mac:CMD+/)
markdown演示
# 一级标题
- 缩进
二、Matplotlib
2.1 Matplotlib
2.1.1 什么是Matplotlib - 画二维图表的python库
mat - matrix 矩阵, 二维数据 - 二维图表
plot - 画图
lib - library 库
matlab 矩阵实验室
mat - matrix
lab 实验室
2.1.2 为什么要学习Matplotlib - 画图
数据可视化 - 帮助理解数据,方便选择更合适的分析方法
js库 - D3 和echarts能实现一些比较酷炫的3D效果
奥卡姆剃刀原理 - 如无必要勿增实体
2.1.3 实现一个简单的Matplotlib画图
import matplotlib.pyplot as pltplt.figure()plt.plot([1,2,3],[4,5,6])plt.show()
2.1.4 拓展知识点:Matplotlib三层结构
容器层: 画板层Canvas 画布层Figure 绘图区/坐标系 x、y轴张成的区域
容器层主要由Canvas、Figure、Axes组成。
Canvas是位于最底层的系统层,在绘图的过程中充当画板的角色,即放置画布(Figure)的工具。
Figure是Canvas.上方的第一层,也是需要用户来操作的应用层的第一层,在绘图的过程中充当画布的角色。
Axs是应用层的第二层,在绘图的过程中相当于画布上的绘图区的角色。
Figure:指整个图形可以通过plt.figure0设置画布的大小和分辨率等)
Axes(坐标系):数据的绘图区域
Axs(坐标轴):坐标系中的一条轴,包含大小限制、刻度和刻度标签
特点为:
一个figure(画布)可以包含多个axes(坐标系/绘图区),但是一个axes只能属于一个figure.
一个axes(坐标系/绘图区)可以包含多个axis(坐标轴),包含两个即为2d坐标系,3个即为3d坐标系
辅助显示层
辅助显示层为Axes(绘图区)内的除了根据数据绘制出的图像以外的内容,主要包括Axes外观(facecolor)边框线(spines)、坐标轴(axis)、坐标轴名称(axis label)、坐标轴刻度(tick)、坐标轴刻度标签(tick label)、网格线(grid)、图例(legend)、标题(title)等内容。
该层的设置可使图像显示更加直观更加容易被用户理解,但又不会对图像产生实质的影响。
图像层
图像层指Axes内通过plot、scatter、bar、histogram、pie等函数根据数据绘制出的图像
总结
Canvas(画板)位于最底层,用户一般接触不到
Figure(画布)建立在Canvas之上
Axes(绘图区)建立在Figure之上
坐标轴(axis)、图例(legend)等辅助显示层以及图像层都是建立在Axes之上
2.2 折线图(plot)与基础绘图功能
2.2.1 折线图绘制与保存图片
基本步骤
创建画布绘制图像显示图像
#1创建画布plt.figure(figsize=(20,8),dpi=80)### figsize : 画布大小### dpi : dot per inch 图像的清晰度,每英寸显示点数#2绘制图像plt.plot([1,2,3,4,5],[6,7,8,9,10])#保存图像(注意保存图片代码应位于plt.show()之前)plt.savefig("test.png")#3显示图像plt.show()#plt.show()会释放figsure资源
2.2.2完善原始折线图(辅助显示层)
# 需求:再添加一个城市的温度变化# 收集到北京当天温度变化情况,温度在1度到3度。 # 1、准备数据 x yx = range(60)y_shanghai = [random.uniform(15, 18) for i in x]y_beijing = [random.uniform(1, 3) for i in x]# 中文显示问题plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签plt.rcParams['axes.unicode_minus']=False #用来正常显示负号# 2、创建画布plt.figure(figsize=(20, 8), dpi=80)# 3、绘制图像plt.plot(x, y_shanghai, color="r", linestyle="-.", label="上海")plt.plot(x, y_beijing, color="b", label="北京")# 显示图例,这里显示图例的前提是plt.plot时要添加标签lsbel=“”plt.legend()#legend有自己的参数可以控制图例位置# 修改x、y刻度# 准备x的刻度说明 ticks表示刻度x_label = ["11点{}分".format(i) for i in x]plt.xticks(x[::5], x_label[::5])#步长为5,即不让刻度显示过于密集第一处的x[::5]也要写,应该是用来给x_label定位的plt.yticks(range(0, 40, 5))# 添加网格显示,其中的alpha是网格的透明程度plt.grid(linestyle="--", alpha=0.5)# 添加描述信息plt.xlabel("时间变化")plt.ylabel("温度变化")plt.title("上海、北京11点到12点每分钟的温度变化状况")# 4、显示图plt.show()
2.2.3多个坐标系显示-plt.subplots(面向对象的画图方法)
注意主要区别就是返回一个figsure和axes,后期全部利用axes[索引]来绘制图像,有一定的函数名字差别 axes[i].方法名()
#主要区别:#figure, axes = plt.subplots(nrows=1, ncols=2, figsize=(20, 8), dpi=80)# 需求:再添加一个城市的温度变化# 收集到北京当天温度变化情况,温度在1度到3度。 # 1、准备数据 x yx = range(60)y_shanghai = [random.uniform(15, 18) for i in x]y_beijing = [random.uniform(1, 3) for i in x]# 2、创建画布# plt.figure(figsize=(20, 8), dpi=80)figure, axes = plt.subplots(nrows=1, ncols=2, figsize=(20, 8), dpi=80)# 3、绘制图像axes[0].plot(x, y_shanghai, color="r", linestyle="-.", label="上海")axes[1].plot(x, y_beijing, color="b", label="北京")# 显示图例axes[0].legend()axes[1].legend()# 修改x、y刻度# 准备x的刻度说明x_label = ["11点{}分".format(i) for i in x]axes[0].set_xticks(x[::5])axes[0].set_xticklabels(x_label)axes[0].set_yticks(range(0, 40, 5))axes[1].set_xticks(x[::5])axes[1].set_xticklabels(x_label)axes[1].set_yticks(range(0, 40, 5))# 添加网格显示axes[0].grid(linestyle="--", alpha=0.5)axes[1].grid(linestyle="--", alpha=0.5)# 添加描述信息axes[0].set_xlabel("时间变化")axes[0].set_ylabel("温度变化")axes[0].set_title("上海11点到12点每分钟的温度变化状况")axes[1].set_xlabel("时间变化")axes[1].set_ylabel("温度变化")axes[1].set_title("北京11点到12点每分钟的温度变化状况")# 4、显示图plt.show()
效果图:
2.2.4 折线图绘制函数图像
import numpy as np# 1、准备x,y数据##表示区间[-1,1]左闭右闭并等间隔生成1000个数字x = np.linspace(-1, 1, 1000)y = 2 * x * x# 2、创建画布plt.figure(figsize=(20, 8), dpi=80)# 3、绘制图像plt.plot(x, y)# 添加网格显示plt.grid(linestyle="--", alpha=0.5)# 4、显示图像plt.show()
2.3 散点图(scatter)
丰富图片的其他函数基本一致,主要区别在于plt.scatter()函数用于绘图
# 需求:探究房屋面积和房屋价格的关系# 1、准备数据x = [225.98, 247.07, 253.14, 457.85, 241.58, 301.01, 20.67, 288.64,163.56, 120.06, 207.83, 342.75, 147.9 , 53.06, 224.72, 29.51,21.61, 483.21, 245.25, 399.25, 343.35]y = [196.63, 203.88, 210.75, 372.74, 202.41, 247.61, 24.9 , 239.34,140.32, 104.15, 176.84, 288.23, 128.79, 49.64, 191.74, 33.1 ,30.74, 400.02, 205.35, 330.64, 283.45]# 2、创建画布plt.figure(figsize=(20, 8), dpi=80)# 3、绘制图像plt.scatter(x, y)# 4、显示图像plt.show()
2.4 柱状图(bar)
##绘制票房分布直方图# 1、准备数据movie_names = ['雷神3:诸神黄昏','正义联盟','东方快车谋杀案','寻梦环游记','全球风暴', '降魔传','追捕','七十七天','密战','狂兽','其它']tickets = [73853,57767,22354,15969,14839,8725,8716,8318,7916,6764,52222]# 2、创建画布plt.figure(figsize=(20, 8), dpi=80)# 3、绘制柱状图x_ticks = range(len(movie_names))plt.bar(x_ticks, tickets,width=[0.2 for i in range(x_ticks)],color=['b','r','g','y','c','m','y','k','c','g','b'])#主要参数x列表,y列表,width列表,color列表# 修改x刻度plt.xticks(x_ticks, movie_names)# 添加标题plt.title("电影票房收入对比")# 添加网格显示plt.grid(linestyle="--", alpha=0.5)# 4、显示图像plt.show()
如果绘制下图的柱状图怎么设置呢,主要在于给x_labels的刻度位置定位,将刻度改变即可
# 1、准备数据movie_name = ['雷神3:诸神黄昏','正义联盟','寻梦环游记']first_day = [10587.6,10062.5,1275.7]first_weekend=[36224.9,34479.6,11830]# 2、创建画布plt.figure(figsize=(20, 8), dpi=80)# 3、绘制柱状图x_ticks=[i for i in range(3)]plt.bar(x_ticks, first_day, width=0.2, label="首日票房")plt.bar([i+0.2 for i in x_ticks], first_weekend, width=0.2, label="首周票房")##########为何是i+0.2呢,因为前面设置的柱状图宽度width=0.2,为了紧密相连,同时没有重合,因此设置0.2# 显示图例plt.legend()# 修改刻度,即显示坐标轴上的数字或字符,本例即显示电影名字plt.xticks([i+0.1 for i in x_ticks], movie_name)###########柱状图宽度为0.2,为了字符名字在中间,因此相对于前面是加了0.1# 4、显示图像plt.show()
2.5 直方图(histogram)
2.5.1 直方图介绍
直方图,形状类似柱状图却有着与柱状图完全不同的含义。直方图牵涉统计学的概念,首先要对数据进行分组,然后统计每个分组内数据元的数量。在坐标系中,横轴标出每个组的端点,纵轴表示频数,每个矩形的高代表对应的频数,称这样的统计图为频数分布直方图。
组数:在统计数据时,我们把数据按照不同的范围分成几个组,分成的组的个数称为组数
组距:每一组两个端点的差
2.5.2 直方图与柱状图的对比
柱状图是以矩形的长度表示每一组的频数或数量,其宽度(表示类别则是固定的,利于较小的数据集分析。
直方图描述的是一组数据的频次分布,是以矩形的长度表示每一组的频数或数量,宽度则表示各组的组距,因此其高度与宽度均有意义,利于展示大量数据集的统计结果。例如把年龄分成“0-5,5-10…80-85”17个组,统计一下中国人口年龄的分布情况。直方图有助于我们知道数据的分布情况,诸如众数、中位数的大致位置、数据是否存在缺口或者异常值。
直方图展示数据的分布,柱状图比较数据的大小。直方图X轴为定量数据,柱状图X轴为分类数据。直方图柱子无间隔,柱状图柱子有间隔直方图柱子宽度可不一,柱状图柱子宽度须一致
2.5.3直方图绘制
可以尝试多种组距以获得一个较好的效果
# 需求:电影时长分布状况# 1、准备数据time = [131, 98, 125, 131, 124, 139, 131, 117, 128, 108, 135, 138, 131, 102, 107, 114, 119, 128, 121, 142, 127, 130, 124, 101, 110, 116, 117, 110, 128, 128, 115, 99, 136, 126, 134, 95, 138, 117, 111,78, 132, 124, 113, 150, 110, 117, 86, 95, 144, 105, 126, 130,126, 130, 126, 116, 123, 106, 112, 138, 123, 86, 101, 99, 136,123, 117, 119, 105, 137, 123, 128, 125, 104, 109, 134, 125, 127,105, 120, 107, 129, 116, 108, 132, 103, 136, 118, 102, 120, 114,105, 115, 132, 145, 119, 121, 112, 139, 125, 138, 109, 132, 134,156, 106, 117, 127, 144, 139, 139, 119, 140, 83, 110, 102,123,107, 143, 115, 136, 118, 139, 123, 112, 118, 125, 109, 119, 133,112, 114, 122, 109, 106, 123, 116, 131, 127, 115, 118, 112, 135,115, 146, 137, 116, 103, 144, 83, 123, 111, 110, 111, 100, 154,136, 100, 118, 119, 133, 134, 106, 129, 126, 110, 111, 109, 141,120, 117, 106, 149, 122, 122, 110, 118, 127, 121, 114, 125, 126,114, 140, 103, 130, 141, 117, 106, 114, 121, 114, 133, 137, 92,121, 112, 146, 97, 137, 105, 98, 117, 112, 81, 97, 139, 113,134, 106, 144, 110, 137, 137, 111, 104, 117, 100, 111, 101, 110,105, 129, 137, 112, 120, 113, 133, 112, 83, 94, 146, 133, 101,131, 116, 111, 84, 137, 115, 122, 106, 144, 109, 123, 116, 111,111, 133, 150]# 2、创建画布plt.figure(figsize=(20, 8), dpi=80)# 3、绘制直方图distance = 2#组距group_num = int((max(time) - min(time)) / distance)#组数=极差/组距plt.hist(time, bins=group_num, density=True)##第一个参数是数据,第二个参数是组数,第三个参数是density默认为False##False显示的是频数,True显示的是频率# 修改x轴刻度plt.xticks(range(min(time), max(time) + 2, distance))# 添加网格plt.grid(linestyle="--", alpha=0.5)# 4、显示图像plt.show()
2.6饼图
用于表示不同分类的占比情况,通过弧度大小来对比各种分类。
特点:分类数据的占比情况(占比)
# 1、准备数据movie_name = ['雷神3:诸神黄昏','正义联盟','东方快车谋杀案','寻梦环游记','全球风暴','降魔传','追捕','七十七天','密战','狂兽','其它']place_count = [60605,54546,45819,28243,13270,9945,7679,6799,6101,4621,5]# 2、创建画布plt.figure(figsize=(20, 8), dpi=80)# 3、绘制饼图plt.pie(place_count, labels=movie_name, colors=['b','r','g','y','c','m','y','k','c','g','y'], autopct="%1.2f%%")# 显示图例plt.legend()plt.axis('equal')##表示横纵轴比相同,即显示为圆形# 4、显示图像plt.show()
三:Numpy
介绍
Numpy(Numerical Python)是一个开源的Python科学计算库,用于快速处理任意维度的数组。Numpy支持常见的数组和矩阵操作。对于同样的数值计算任务,使用Numpy比直接使用Python要简洁的多。Numpy使用ndarray对象来处理多维数组,该对象是一个快速而灵活的大数据容器。ndarray
Numpy提供了一个N dimension array,即n维数组
numpy与list对比
存储风格:
ndarray 内部存储类型相同,存储空间连续,但通用性不强
list 内部存储类型可以不同,存储空间未必连续,通用性较强
并行化计算:ndarray支持向量化运算
底层语言:
Numpy底层采用C语言编写,内部解除了GIL(全局解释器锁),其对数组的操作速度不受Python解释器的限制,效率远高于纯Python代码。
属性方法
3.1基本操作
3.1.1ndarray形状和类型
形状
import numpy as npa = np.array([[1,2,3],[4,5,6]]) #(2,3) b = np.array([1,2,3,4]) #(4,) c = np.array([[[1,2,3],[4,5,6]],[[1,2,3],[4,5,6]]])#(2,2,3)
类型
创建数组时指定即可
# 创建数组的时候指定类型np.array([1.1, 2.2, 3.3], dtype="float32")
3.1.2生成数组
生成0 1 数组
# 1 生成0和1的数组a=np.zeros(shape=(3, 4), dtype="float32")##其中shape的参数为列表/元组均可,用于表示生成的数组维度
从现有数组生成
a1=np.array(a) #深拷贝a2=np.copy(a) #深拷贝a3=np.asarray(a)#浅拷贝a4=a#浅拷贝
生成固定范围的数组
np.linspace(0, 10, 5) # 生成[0,10]之间等距离的5个数,左右均为闭区间np.arange(0, 11, 5) # [0,11),5为步长生成数组 ,左闭右开
生成随机数组
# 生成均匀分布的一组数[low,high) 左闭右开,size是数量data1 = np.random.uniform(low=-1, high=1, size=1000000)########注意这两处的size都可以规定数组形状 size=(8,100)# 生成正态分布的一组数,loc:均值;scale:标准差,size数量data2 = np.random.normal(loc=1.75, scale=0.1, size=1000000)
3.1.3索引切片
stock_change = np.random.normal(loc=0, scale=1, size=(8, 10))# 获取第一个股票的前3个交易日的涨跌幅数据print(stock_change[0, :3])a[1, 0, 2] = 1000a[1][0][2] = 1000
3.1.4形状改变
stock_change.reshape((10, 8)) # 返回新的ndarray, 原始数据没有改变stock_change.resize((10, 8)) # 没有返回值, 对原始的ndarray进行了修改stock_change.T # 转置 行变成列,列变成行 返回一个ndarray,原数据未改变##reshape()是一个函数,因此第一个括号是函数个括号,而第二个括号是因为传入了一个元##组,其实用列表也可
3.1.5类型修改
stock_change.astype("int32")stock_change.tostring() # ndarray序列化到本地??????
/u010356210/article/details/106131209
3.1.6数组去重
temp = np.array([[1, 2, 3, 4],[3, 4, 5, 6]])np.unique(temp)set(temp.flatten())##set的操作对象需要时一维的,.flatten()可以压缩为一维的
3.2ndarray运算
3.2.1逻辑运算
运算符stock_change = np.random.uniform(low=-1, high=1, size=(5,10))# 逻辑判断, 如果涨跌幅大于0.5就标记为True 否则为Falsestock_change > 0.5#返回一个True和False的等大小矩阵stock_change[stock_change > 0.5] = 1.1 #将>0.5的全部改为1
通用判断函数
#以下两者均只返回一个布尔值# 判断stock_change[0:2, 0:5]是否全是上涨的np.all(stock_change[0:2, 0:5] > 0) # 判断前5只股票这段期间是否有上涨的np.any(stock_change[:5, :] > 0)
三元运算符
# np.where(布尔表达式,True的位置的值,False的位置的值),类似于三元运算符,不# 过需要利用函数np.where(temp > 0, 1, 0)###涉及符合逻辑需要额外的函数logical_and/or# 大于0.5且小于1np.where(np.logical_and(temp > 0.5, temp < 1), 1, 0)# 大于0.5或小于-0.5np.where(np.logical_or(temp > 0.5, temp < -0.5), 11, 3)
3.2.2统计运算
主要函数:min max mean median(中位数) var(方差) std(标准差)使用方法:np.函数名(数组名) 或 数组名.方法名同时应当注意 axis的使用。 axis=0表示列 axis=1表示行 axis=-1 表示最后一维度###返回值stock_change.max() #将返回最大值np.max(stock_change,axis=1)#将返回一个向量,即所有行的最大值###返回索引np.argmax(tem,axis=0)np.argmin(tem,axis=0)
3.2.3数组运算
数组与数字的运算
正常的运算即可加减乘除等
数组与数组的运算
广播机制
执行broadcast的前提在于,两个nadarray执行的是element-wise的运算,Broadcast机制的功能是为了方便不同形状的ndarray(numpy库的核心数据结构)进行数学运算。
当操作两个数组时,numpy会逐个比较它们的shape(构成的元组tuple),只有在下述情况下,两个数组才能够进行数组与数组的运算。
维度相等shape(其中相对应的一个地方为1)
具体解释解释就是看这个图。
比如(不一定是乘法)数组A*B,将两者的维度写出,如下,将维度从尾部开始对齐,则满足运算的要求是:
对应的维度相同 若维度不同,则其中一个维度应当为1
矩阵运算
可以通过np.mat(array)将数组转化为矩阵
矩阵的乘法必须满足运算规则,即(m,n)*(n,l)=(m,l)
如果是二维数组实现矩阵运算
np.dot(data,data1)np.matmul(data,data1)data @ data1
如果是矩阵进行运算
data1*data2
3.2.4数组合并分割
numpy.hstack 水平拼接
numpy.vstack 竖拼接
numpy.concatenate((a1,a2),axis=0|1) 水平|竖拼接
np.hstack((a, b))np.vstack((a, b))np.concatenate((a, b), axis=1)
四:Pandas
4.0基本介绍
Pandas=panel+data+analysis专门用于数据挖掘的开源Python库以Numpy为基础,借力Numpy模块在计算方面性能高的优势基于matplotlib,能够简便的画图独特的数据结构便捷的数据处理能力读取文件方便封装了Matplotlib、Numpy的画图和计算核心数据结构
DataFrame (是series的容器,一般二维)Panel(是dataframe的容器,三维)Series(一维)
4.1DataFrame
4.1.0DataFrame结构
索引:行索引-index,横向索引;列索引-columns,纵向索引值:values,利用values即可直接获得去除索引的数据(数组)shape:表明形状 (形状不含索引的行列)T:行列转置4.1.1构造dataframe 利用DataFrame函数
DataFrame是一个既有行索引又有列索引的二维数据结构
import numpy as npimport pandas as pd a=np.ones((2,3))b=pd.DataFrame(a)
如图,生成的打他frame是一个二维表,由于没有指定索引,因此默认行列索引为数字序号
4.1.2常用操作(设置索引)
获取局部展示
b.head()#默认展示前5行,可在head()加入数字,展示前几行b.tail()#默认展示后5行,可在tail()加入数字,展示后几行
获取索引和值
b.index#获取行索引#####返回一个类似列表的东西,也可以利用数字继续索引例:a.index[1]b.columns#获取列索引b.values#获取数据值(数组,不含索引)b.shape#获取DataFrame的维度数据b.T#获取转制后的dataframe
设置行列索引
# 创建一个符合正态分布的10个股票5天的涨跌幅数据stock_change = np.random.normal(0, 1, (10, 5))pd.DataFrame(stock_change)#设置行列索引stock = ["股票{}".format(i) for i in range(10)]date = pd.date_range(start="0101", periods=5, freq="B")#这个是pandas中设置日期的# 添加行列索引data = pd.DataFrame(stock_change, index=stock, columns=date)
修改索引
#不能单独修改行列总某一个索引的值,可以替换整行或整列 例:b.index[2]='股票1' 错误data.index=新行索引#重设索引data.reset_index(drop=False)#drop参数默认为False,表示将原来的索引替换掉,换新索引为数字递增,原来的索引将变为数据的一部分。True表示,将原来的索引删除,更换为数字递增。如下图
# 设置新索引df = pd.DataFrame({'month': [1, 4, 7, 10],'year': [, , , ],'sale':[55, 40, 84, 31]})# 以月份设置新的索引df.set_index("month", drop=True)#见下图,即将原本数据中的一列拿出来作为indexnew_df = df.set_index(["year", "month"])# 设置多个索引,以年和月份 多个索引其实就是MultiIndex
可以看到下面的new_df已经是multiIndex类型数据了。
有三级:index index.names index.levels
分别看各自的输出
4.1.3 MultiIndex与Panel
MultiIndex:多级或分层索引对象
MultiIndex详解
Panel:
pandas.Panel(data=None,items=None,major_axis=None,minor_axis=None,copy=False,dtype=None)
存储3维数组的Panel结构
items - axis 0,每个项目对应于内部包含的数据帧(DataFrame)。major_axis - axis 1,它是每个数据帧(DataFrame)的索引(行)。minor_axis - axis 2,它是每个数据帧(DataFrame)的列。
p = pd.Panel(np.arange(24).reshape(4,3,2),items=list('ABCD'),major_axis=pd.date_range('0101', periods=3),minor_axis=['first', 'second'])p["A"]p.major_xs("-01-01")p.minor_xs("first")###由于panel是三维数据,因此只能从某一个维度切入,可以理解为从立方体中抽出一个平面(dataframe)观察,则上面三行代码结果如下图;而series则是相当于从平面(dataframe)中抽出一行或一列来观察
Pandas从版本0.20.0开始弃用,推荐的用于表示3D数据的方法是DataFrame上的MultiIndex方法
4.1.4 Series
带索引的一维数组
indexvalues
# 创建pd.Series(np.arange(3, 9, 2), index=["a", "b", "c"])# 或pd.Series({'red':100, 'blue':200, 'green': 500, 'yellow':1000})sr = data.iloc[1, :]sr.index # 索引sr.values # 值#####就是从dataframe中抽出一行或一列来观察
4.2基本数据操作(很重要的一点是布尔值索引)
4.2.1索引操作(bool索引见4.2.4)
data=pd.read_csv("./stock_day/stock_day.csv")#读入文件的前5行表示如下######利用drop删除某些行列,需要利用axis告知函数是行索引还是列索引data=data.drop(["ma5","ma10","ma20","v_ma5","v_ma10","v_ma20"], axis=1) # 去掉一些不要的列data["open"]["-02-26"] # 直接索引,但需要遵循先列后行#####按名字索引利用.loc函数可以不遵循列行先后关系data.loc["-02-26"]["open"] # 按名字索引data.loc["-02-26", "open"]#####利用.iloc函数可以只利用数字进行索引data.iloc[1][0] # 数字索引data.iloc[1,0]# 组合索引# 获取行第1天到第4天,['open', 'close', 'high', 'low']这个四个指标的结果data.ix[:4, ['open', 'close', 'high', 'low']] # 现在不推荐用了###但仍可利用loc和ilocdata.loc[data.index[0:4], ['open', 'close', 'high', 'low']]data.iloc[0:4, data.columns.get_indexer(['open', 'close', 'high', 'low'])]
4.2.2赋值操作
data仍然是上图类型
data.open=100data['open']=100###两种方式均可data.iloc[1,0]=100###找好索引即可
4.2.3排序
sort_values (比较values进行排序) sort_index (比较行索引进行排序,不行可以先转置简介对列排序)
data.sort_values(by="high", ascending=False) # DataFrame内容排序,ascending表示升序还是降序,默认True升序data.sort_values(by=["high", "p_change"], ascending=False).head() # 多个列内容排序。给出的优先级进行排序data.sort_index(ascending=True)###对行索引进行排序#这里是取出了一列 “price_change”列,为serise,用法同上sr = data["price_change"]sr.sort_values(ascending=False)sr.sort_index()
4.2.4数学运算 布尔值索引
算术运算:直接利用运算符或者函数
#正常的加减乘除等的运算即可data["open"] + 3data["open"].add(3) # open统一加3 data.sub(100)# 所有统一减100 data - 100(data["close"]-(data["open"])).head() # close减open
逻辑运算 :< ; > ; | ; & 利用逻辑符号或者函数query
# 例如筛选p_change > 2的日期数据data[data["p_change"] > 2].head()# 完成一个多个逻辑判断, 筛选p_change > 2并且low > 15data[(data["p_change"] > 2) & (data["low"] > 15)].head()data.query("p_change > 2 & low > 15").head()###等效于上一行代码###判断# 判断'turnover'列索引中是否有4.19, 2.39,将返回一列布尔值data["turnover"].isin([4.19, 2.39])##如下图
利用布尔值索引,即利用一个布尔数组索引出True的数据
###判断# 判断'turnover'列索引中是否有4.19, 2.39,将返回一列布尔值data["turnover"].isin([4.19, 2.39])##如下图data[data["turnover"].isin([4.19, 2.39])]#这块就将返回turnover列布尔值为true的如下图,也就是筛选出turnover中值为4.19和2.39###布尔值索引是一个很方便的数据筛选操作,比如:data[data["turnover"]>0.1]#也将筛选出turnover列中大于0.1的整体data数据,并不是说只返回turnover相关数据,判断只是返回布尔索引,利用索引的是data数据
4.2.5统计运算
data.describe()#将返回关于列的最值,均值,方差等多种信息##其实这里很多就和numpy相似了data.max(axis=0)#返回最值data.idxmax(axis=0) #返回最值索引
累计统计函数(累加,累乘等)
cumsum 计算前1/2/3/…/n个数的和cummax 计算前1/2/3/…/n个数的最大值cummin 计算前1/2/3/…/n个数的最小值cumprod 计算前1/2/3/…/n个数的积
自定义运算
apply(func, axis=0)
func: 自定义函数
axis=0: 默认按列运算,axis=1按行运算
data.apply(lambda x: x.max() - x.min())#这里的lambda x: x.max() - x.min()是lambda表达式,是函数的简单写法也可def fx(data):returndata.max()-data.min()
4.3画图
pandas.DataFrame.plot
DataFrame.plot(x=None, y=None, kind=‘line’)
x: label or position, default Noney: label, position or list of label, positions, default None Allows plotting of one column versus another kind: str ‘line’: line plot(default)''bar": vertical bar plot“barh”: horizontal bar plot“hist”: histogram“pie”: pie plot“scatter”: scatter plot
#更简易用matplotlibdata.plot(x="volume", y="turnover", kind="scatter")data.plot(x="high", y="low", kind="scatter")data['volume'].plot()
4.4文件读取写入
4.4.1 CSV文件
DataFrame.to_csv(path_or_buf=None,sep=','columns=None,header=True,index=True,index_label=None,mode='w',encoding=None)
path_or_buf:string or file handle , default Nonesep: character, default ‘,’(分隔符)columns:sequence,optionalmode:'w‘:重写,'a’追加index:是否写入 行索引header:boolean or list of string,default True,是否写进列索引值
Series.to_csv (path=None,index=True,sep=',',na_rep='',float_format=None,header=False,index_label=None,mode='w',encoding=None,compression=None,date_format=None,decimal='.)
Write Series to a comma-separated values(csv)file
pd.read_csv("./stock_day/stock_day.csv", usecols=["high", "low", "open", "close"]).head() # 读哪些列data = pd.read_csv("stock_day2.csv", names=["open", "high", "close", "low", "volume", "price_change", "p_change", "ma5", "ma10", "ma20", "v_ma5", "v_ma10", "v_ma20", "turnover"]) # 如果列没有列名,用names传入data[:10].to_csv("test.csv", columns=["open"]) # 保存open列数据data[:10].to_csv("test.csv", columns=["open"], index=False, mode="a", header=False) # 保存opend列数据,index=False不要行索引,mode="a"追加模式|mode="w"重写,header=False不要列索引
csv可以用excel表格打开,但是可能有格式错误
4.4.2HDF5文件
read_hdf to_hdf
HDF5文件的读取和存储需要指定一个键,值为要存储的DataFrame,也就是说hdf5存储的是panel这种三维类型,一个key对应一个dataframe
pandas.read_hdf(path_or_buf, key=None, **kwargs)
从h5文件当中读取数据
path_or_buffer: 文件路径key: 读取的键mode: 打开文件的模式reurn: The Selected object
DataFrame.to_hdf(path_or_buf, key, **kwargs)
day_close = pd.read_hdf("./stock_data/day/day_close.h5",key="close")day_close.to_hdf("test.h5",key="close" )
4.4.3 JSON文件
read_json to_json
pandas.read_json(path_or_buf=None,orient=None,typ=“frame”,lines=False)
将JSON格式转换成默认的Pandas DataFrame格式orient: string,Indication of expected JSON string format. ‘split’: dict like {index -> [index], columns -> [columns], data -> [values]}‘records’: list like [{column -> value}, …, {column -> value}]‘index’: dict like {index -> {column -> value}}‘columns’: dict like {column -> {index -> value}}, 默认该格式‘values’: just the values array lines: boolean, default False 按照每行读取json对象 typ: default ‘frame’,指定转换成的对象类型series或者dataframe
sa = pd.read_json("Sarcasm_Headlines_Dataset.json", orient="records", lines=True)##主要是path,orient是一种确定索引与数值的对应,以本例来看,列索引就是‘key’,values就是key对应的值sa.to_json("test.json", orient="records", lines=True)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1nR980In-1647746935684)(python数据挖掘.assets/image-0319221645419.png)]
本示例中按行存储,每行是一个字典,键 有’article_link’,'headline’等
数据读取后的展示如下
4.5高级处理
4.5.1缺失值(标记值)处理
主要参数
inplace实现数据替换(默认为False)dropna实现缺失值的删除(默认删除行)fillna实现缺失值的填充isnull或notnull判断是否有缺失数据NaN
如何进行缺失值处理?
删除含有缺失值的样本替换/插补数据
判断NaN是否存在
pd.isnull(df) 会返回整个dataframe的布尔框架,难以观察(bool为True代表那个位置是缺失值)pd.isnull(df).any() 表示只要有一个True就返回Truepd.notnull(df)会返回整个dataframe的布尔框架,难以观察(bool为False代表那个位置是缺失值)pd.notnull(df).all() 表示只要有一个False就返回False
删除nan数据
df.dropna(inplace=True) 默认按行删除 inplace:True修改原数据,False返回新数据,默认False
替换nan数据
df.fillna(value,inplace=True)
value替换的值
inplace:True修改原数据,False返回新数据,默认False
movie["Revenue (Millions)"].fillna(movie["Revenue (Millions)"].mean(), inplace=True)###这就是先利用其他代码判断出"Revenue (Millions)"有nan数据,然后利用.fillna函数,令value=movie["Revenue (Millions)"].mean()列的均值,然后inplace=True修改原数据
import pandas as pdimport numpy as npmovie = pd.read_csv("./IMDB/IMDB-Movie-Data.csv")# 1)判断是否存在NaN类型的缺失值np.any(pd.isnull(movie)) # 返回True,说明数据中存在缺失值np.all(pd.notnull(movie)) # 返回False,说明数据中存在缺失值pd.isnull(movie).any()pd.notnull(movie).all()# 2)缺失值处理# 方法1:删除含有缺失值的样本data1 = movie.dropna()pd.notnull(data1).all()# 方法2:替换# 含有缺失值的字段# Revenue (Millions) # Metascoremovie["Revenue (Millions)"].fillna(movie["Revenue (Millions)"].mean(), inplace=True)movie["Metascore"].fillna(movie["Metascore"].mean(), inplace=True)
替换非nan的标记数据
有些数据不存在可能标记为“#”,“?”等
# 读取数据path = "wisconsin.data"name = ["Sample code number", "Normal Nucleoli","Mitoses", "Class"]data = pd.read_csv(path, names=name)#这里的非nan标记值缺失值就是利用“?”表示的,因此利用参数to_replace,value=np.nan,将默认标记值替换为nan值,然后再利用签署方法处理nan缺失值# 1)替换data_new = data.replace(to_replace="?", value=np.nan)
4.5.2 离散化
这一块建议去看视频,理解更快:视频地址
连续属性的离散化就是将连续属性的值域上,将值域划分为若干个离散的区间,最后用不同的符号或整数 值代表落在每个子区间的属性值。
连续属性离散化的目的是为了简化数据结构,数据离散化技术可以用来减少给定连续属性值的个数。离散化方法经常作为数据挖掘的工具。
实现方法:
分组 自动分组 sr = pd.qcut(data, bins)自定义分组 sr = pd.cut(data, []) 将分组好的结果转换成one-hot编码(哑变量) pd.get_dummies(sr, prefix=)
one-hot编码:
one-hot
比如男女数据一般用1和0表示,但1和0本身有大小问题,而男女只是不同的概念,因此用1,0表示会存在区别
如果用one-hot表示一种方法可以是,相当于利用一种编码的方式表示
同时还可处理连续数据,比如将身高的连续数据分为不同的身高区间,每个区间对应一个类别,然后类比同上来考虑
# 1)准备数据data = pd.Series([165,174,160,180,159,163,192,184], index=['No1:165', 'No2:174','No3:160', 'No4:180', 'No5:159', 'No6:163', 'No7:192', 'No8:184']) # 2)分组# 自动分组sr = pd.qcut(data, 3)sr.value_counts() # 看每一组有几个数据# 3)转换成one-hot编码pd.get_dummies(sr, prefix="height")# 自定义分组bins = [150, 165, 180, 195]#这就表示有三组[150,165][165,180][180,195]sr = pd.cut(data, bins)# get_dummiespd.get_dummies(sr, prefix="身高")
4.5.3合并
指合并不同dataframe上的内容数据
按方向
pd.concat([data1, data2], axis=1) #axis:0为列索引;1为行索引
按索引
merge函数参数API
left = pd.DataFrame({'key1': ['K0', 'K0', 'K1', 'K2'],'key2': ['K0', 'K1', 'K0', 'K1'],'A': ['A0', 'A1', 'A2', 'A3'],'B': ['B0', 'B1', 'B2', 'B3']})right = pd.DataFrame({'key1': ['K0', 'K1', 'K1', 'K2'],'key2': ['K0', 'K0', 'K0', 'K0'],'C': ['C0', 'C1', 'C2', 'C3'],'D': ['D0', 'D1', 'D2', 'D3']})pd.merge(left, right, how="inner", on=["key1", "key2"])pd.merge(left, right, how="left", on=["key1", "key2"])pd.merge(left, right, how="outer", on=["key1", "key2"])###这里merge参数解释:#left: 需要合并的一个表,合并后在左侧#right:需要合并的一个表,合并后在右侧#how: 合并方式#on: 在哪些索引上进行合并
4.5.4交叉表与透视表
交叉表
交叉表用于计算一列数据对于另外一列数据的分组个数(寻找两个列之间的关系)
pd.crosstab(value1, value2)
data = pd.crosstab(stock["week"], stock["pona"])data.div(data.sum(axis=1), axis=0).plot(kind="bar", stacked=True)
透视表
相对于交叉表操作简单些
# 透视表操作stock.pivot_table(["pona"], index=["week"])
4.5.6分组与聚合
分组与聚合通常是分析数据的一种方式,通常与一些统计函数一起使用,查看数据的分组情况。
DataFrame.groupby(key, as_index=False) key:分组的列数据,可以多个
col =pd.DataFrame({'color': ['white','red','green','red','green'], 'object': ['pen','pencil','pencil','ashtray','pen'],'price1':[5.56,4.20,1.30,0.56,2.75],'price2':[4.75,4.12,1.60,0.75,3.15]})# 进行分组,对颜色分组,price1进行聚合# 用dataframe的方法进行分组col.groupby(by="color")# 或者用Series的方法进行分组聚合col["price1"].groupby(col["color"])
效果图
五:案例
要求
想知道这些电影数据中评分的平均分,导演的人数等信息,我们应该怎么获取?对于这一组电影数据,如果我们想看Rating,Runtime(Minutes)的分布情况,应该如何呈现数据?对于这一组电影数据,如果我们希望统计电影分类(genre)的情况,应该如何
处理数据?
数据结构展示
数据网址
代码
# 1、准备数据movie = pd.read_csv("./IMDB/IMDB-Movie-Data.csv")###movie读入后如上图所示######################问题一# 问题1:我们想知道这些电影数据中评分的平均分,导演的人数等信息,我们应该怎么获取?# 评分的平均分movie["Rating"].mean()# 导演的人数np.unique(movie["Director"]).size######################问题二##绘制直方图查看分布movie["Rating"].plot(kind="hist", figsize=(20, 8))#利用matplotlib可更细致绘图import matplotlib.pyplot as plt# 1、创建画布plt.figure(figsize=(20, 8), dpi=80)# 2、绘制直方图plt.hist(movie["Rating"], 20)# 修改刻度plt.xticks(np.linspace(movie["Rating"].min(),movie["Rating"].max(), 21))# 添加网格plt.grid(linestyle="--", alpha=0.5)# 3、显示图像plt.show()######################问题三##如果我们希望统计电影分类(genre)的情况,应该如何处理数据?###可以发现图中genre一列数据中每个电影都有多种标签,因此要先分割# 先统计电影类别都有哪些movie_genre = [i.split(",") for i in movie["Genre"]]###得到的movie_genre结构图见《下图一》###这一块主要是把movie_genre的二维列表变为以为列表,然后利用unique函数去重movie_class = np.unique([j for i in movie_genre for j in i])len(movie_class)####这就得到了电影的类型标签种类数# 统计每个类别有几个电影count = pd.DataFrame(np.zeros(shape=[1000, 20], dtype="int32"), columns=movie_class)count.head()###得到的count结构如《下图二》# 计数填表for i in range(1000):count.ix[i, movie_genre[i]] = 1###注意ix现在不太能用了############movie_genre[i]将返回字符索引列#这就得到了下面第三张图片的数据处理效果,列表示电影类型种类,行表示不同电影,如《下图三》#因此只需逐列求和即可得到每类标签电影的数量##最终实现数据可视化如《下图四》count.sum(axis=0).sort_values(ascending=False).plot(kind="bar", figsize=(20, 9), fontsize=40, colormap="cool")
图一
图二
图三
图四