数据分析处理快速上手教程matplotlib+numpy+pandas(基础讲解)

数据分析处理快速上手教程matplotlib+numpy+pandas(基础讲解),第1张

文章目录
  • python数据挖掘
    • 一、数据挖掘基础环境安装与使用
      • 1.1 库的安装
      • 1.2 Jupyter Notebook使用
        • 1.2.1 Jupyter Notebook介绍
        • 1.2.2 为什么使用Jupyter Notebook?
        • 1.2.3 Jupyter Notebook的使用-helloworld
    • 二、Matplotlib
      • 2.1 Matplotlib
        • 2.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
      • 介绍
      • ndarray
      • numpy与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数组合并分割
    • 四:Pandas
      • 4.0基本介绍
      • 4.1DataFrame
        • 4.1.0DataFrame结构
        • 4.1.1构造dataframe 利用**DataFrame**函数
        • 4.1.2常用 *** 作(设置索引)
        • 4.1.3 MultiIndex与Panel
        • 4.1.4 Series
      • 4.2基本数据 *** 作(很重要的一点是布尔值索引)
        • 4.2.1索引 *** 作(bool索引见4.2.4)
        • 4.2.2赋值 *** 作
        • 4.2.3排序
        • 4.2.4数学运算 布尔值索引
        • 4.2.5统计运算
      • 4.3画图
      • pandas.DataFrame.plot
      • 4.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 (pydata.org)
哔哩哔哩网课
走在小路上 笔记

一、数据挖掘基础环境安装与使用 1.1 库的安装
  1. pip install

  2. 集合到requirements.txt文件中集成安装

    matplotlib==2.2.2
    numpy==1.14.2
    pandas==0.20.3
    TA-Lib==0.4.16 技术指标库
    tables==3.4.2 hdf5
    jupyter==1.0.0 数据分析与展示的平台
    

    pip install -r requirments.txt

1.2 Jupyter Notebook使用 1.2.1 Jupyter Notebook介绍
  1. web版的ipython
  2. 名字缘由ju - Julia
    py - Python
    ter - R
    Jupiter 木星 宙斯
  3. 编程、写文档、记笔记、展示
  4. 文件是.ipynb
1.2.2 为什么使用Jupyter Notebook?
  1. 画图方面的优势
  2. 数据展示方面的优势
1.2.3 Jupyter Notebook的使用-helloworld
  1. 界面启动、创建文件

    在终端输入jupyter notebook / ipython notebook

    注意可以是pycharm中的终端,也可以直接是windows终端,不过要将路径调整到你的项目路径

    如图
    然后点击网址即可
    ​ 快速上手的方法:
    ​ 快捷键
    ​ 运行代码 shift + enter

  2. 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+/)

  1. 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 plt
plt.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. 创建画布
  2. 绘制图像
  3. 显示图像
#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 y
x = 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 y
x = 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个组,统计一下中国人口年龄的分布情况。直方图有助于我们知道数据的分布情况,诸如众数、中位数的大致位置、数据是否存在缺口或者异常值。

    1. 直方图展示数据的分布,柱状图比较数据的大小。
    2. 直方图X轴为定量数据,柱状图X轴为分类数据。
    3. 直方图柱子无间隔,柱状图柱子有间隔
    4. 直方图柱子宽度可不一,柱状图柱子宽度须一致
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,20105]

# 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对比
  1. 存储风格:

    ndarray 内部存储类型相同,存储空间连续,但通用性不强

    list 内部存储类型可以不同,存储空间未必连续,通用性较强

  2. 并行化计算:ndarray支持向量化运算

  3. 底层语言:
    Numpy底层采用C语言编写,内部解除了GIL(全局解释器锁),其对数组的 *** 作速度不受Python解释器的限制,效率远高于纯Python代码。

属性方法
属性名字属性解释
ndarray.shape数组维度的元组
ndarray.ndim数组维数
ndarray.size数组中的元素数量
ndarray.itemsize一个数组元素的长度(字节)
ndarray.dtype数组元素的类型
使用方法 数组名.函数名
3.1基本 *** 作 3.1.1ndarray形状和类型

形状

import numpy as np
a = 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] = 1000
a[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序列化到本地??????

https://blog.csdn.net/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 否则为False
stock_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且小于1
    np.where(np.logical_and(temp > 0.5, temp < 1), 1, 0)
    # 大于0.5或小于-0.5
    np.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. ​ 对应的维度相同
  2. ​ 若维度不同,则其中一个维度应当为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 np
import pandas as pd 
a=np.ones((2,3))
b=pd.DataFrame(a)

如图,生成的打他frame是一个二维表,由于没有指定索引,因此默认行列索引为数字序号

4.1.2常用 *** 作(设置索引)
  1. 获取局部展示

    b.head()#默认展示前5行,可在head()加入数字,展示前几行
    b.tail()#默认展示后5行,可在tail()加入数字,展示后几行
    
  2. 获取索引和值

    b.index#获取行索引
    #####返回一个类似列表的东西,也可以利用数字继续索引例:a.index[1]
    b.columns#获取列索引
    b.values#获取数据值(数组,不含索引)
    b.shape#获取DataFrame的维度数据
    b.T#获取转制后的dataframe
    
  3. 设置行列索引

    # 创建一个符合正态分布的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="20200101", periods=5, freq="B")#这个是pandas中设置日期的
    # 添加行列索引
    data = pd.DataFrame(stock_change, index=stock, columns=date)
    
  4. 修改索引

    #不能单独修改行列总某一个索引的值,可以替换整行或整列   例:b.index[2]='股票1'  错误
    data.index=新行索引
    #重设索引
    data.reset_index(drop=False)
    #drop参数默认为False,表示将原来的索引替换掉,换新索引为数字递增,原来的索引将变为数据的一部分。True表示,将原来的索引删除,更换为数字递增。如下图
    

# 设置新索引
df = pd.DataFrame({'month': [1, 4, 7, 10],
                    'year': [2012, 2014, 2013, 2014],
                    'sale':[55, 40, 84, 31]})
# 以月份设置新的索引
df.set_index("month", drop=True)
#见下图,即将原本数据中的一列拿出来作为index
new_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('20130101', periods=3),
                 minor_axis=['first', 'second'])
p["A"]
p.major_xs("2013-01-01")
p.minor_xs("first")
###由于panel是三维数据,因此只能从某一个维度切入,可以理解为从立方体中抽出一个平面(dataframe)观察,则上面三行代码结果如下图;而series则是相当于从平面(dataframe)中抽出一行或一列来观察

Pandas从版本0.20.0开始弃用,推荐的用于表示3D数据的方法是DataFrame上的MultiIndex方法

4.1.4 Series

带索引的一维数组

  • index
  • values
# 创建
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"]["2018-02-26"] # 直接索引,但需要遵循先列后行

#####按名字索引利用.loc函数可以不遵循列行先后关系
data.loc["2018-02-26"]["open"] # 按名字索引
data.loc["2018-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和iloc
data.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=100
data['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数学运算 布尔值索引
  1. 算术运算:直接利用运算符或者函数

    #正常的加减乘除等的运算即可
    data["open"] + 3
    data["open"].add(3) # open统一加3  
    data.sub(100)# 所有统一减100 data - 100
    (data["close"]-(data["open"])).head() # close减open
    
  2. 逻辑运算 :< ; > ; | ; & 利用逻辑符号或者函数query

    # 例如筛选p_change > 2的日期数据
    data[data["p_change"] > 2].head()
    # 完成一个多个逻辑判断, 筛选p_change > 2并且low > 15
    data[(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])##如下图
    

  1. 利用布尔值索引,即利用一个布尔数组索引出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):
	return	data.max()-data.min()
4.3画图 pandas.DataFrame.plot

DataFrame.plot(x=None, y=None, kind=‘line’)

  • x: label or position, default None
  • y: 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
#更简易用matplotlib
data.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 None
  • sep : character, default ‘,’(分隔符)
  • columns :sequence,optional
  • mode:'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-20220319221645419.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就返回True
  • pd.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 pd
import numpy as np
movie = 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)    
# Metascore
movie["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 离散化

这一块建议去看视频,理解更快:视频地址

  • 连续属性的离散化就是将连续属性的值域上,将值域划分为若干个离散的区间,最后用不同的符号或整数 值代表落在每个子区间的属性值。

  • 连续属性离散化的目的是为了简化数据结构,数据离散化技术可以用来减少给定连续属性值的个数。离散化方法经常作为数据挖掘的工具。

  • 实现方法:

    1. 分组
      • 自动分组 sr = pd.qcut(data, bins)
      • 自定义分组 sr = pd.cut(data, [])
    2. 将分组好的结果转换成one-hot编码(哑变量)
      • pd.get_dummies(sr, prefix=)
  • one-hot编码:
    one-hot

    比如男女数据一般用1和0表示,但1和0本身有大小问题,而男女只是不同的概念,因此用1,0表示会存在区别

    (男:1 女:0)性别
    小明1
    小红0

    如果用one-hot表示一种方法可以是,相当于利用一种编码的方式表示

    编码
    小明101 0
    小红010 1

    同时还可处理连续数据,比如将身高的连续数据分为不同的身高区间,每个区间对应一个类别,然后类比同上来考虑

    # 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_dummies
    pd.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交叉表与透视表
  1. 交叉表

    • 交叉表用于计算一列数据对于另外一列数据的分组个数(寻找两个列之间的关系)

    • pd.crosstab(value1, value2)

      data = pd.crosstab(stock["week"], stock["pona"])
      data.div(data.sum(axis=1), axis=0).plot(kind="bar", stacked=True)
      
  2. 透视表

    • 相对于交叉表 *** 作简单些

      # 透视表 *** 作
      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"])
    

    效果图

五:案例

要求

  1. 想知道这些电影数据中评分的平均分,导演的人数等信息,我们应该怎么获取?
  2. 对于这一组电影数据,如果我们想看Rating,Runtime(Minutes)的分布情况,应该如何呈现数据?
  3. 对于这一组电影数据,如果我们希望统计电影分类(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")

图一
图二
图三
图四

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/870558.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-13
下一篇 2022-05-13

发表评论

登录后才能评论

评论列表(0条)

保存