机器学习是从数据中自动分析获得模型,并利用模型对未知数据进行预测。
机器学习工作流程总结
数据简介
在数据集中一般:
数据类型构成:
数据分割:
机器学习一般的数据集会划分为两个部分:
即对数据进行缺失值、去除异常值等处理
特征工程是使用专业背景知识和技巧处理数据,使得特征能在机器学习算法上发挥更好的作用的过程。
意义:会直接影响机器学习的效果
特征工程包含内容
特征提取:将任意数据(如文本或图像)转换为可用于机器学习的数字特征
特征预处理:通过一些转换函数将特征数据转换成更加适合算法模型的特征数据过程
特征降维:指在某些限定条件下,降低随机变量(特征)个数,得到一组“不相关”主变量的过程
选择合适的算法对模型进行训练
对训练好的模型进行评估
根据数据集组成不同,可以把机器学习算法分为:
按照数据集的目标值不同,可以把模型评估分为分类模型评估和回归模型评估。
模型评估用于评价训练好的的模型的表现效果,其表现效果大致可以分为两类:过拟合、欠拟合。
requirements.txt
matplotlib==2.2.2
numpy==1.14.2
pandas==0.20.3
tables==3.4.2
jupyter==1.0.0
pip3 install -r requirements.txt
Jupyter支持两种模式:
快捷键操作
两种模式通用快捷键
Shift+Enter,执行本单元代码,并跳转到下一单元
Ctrl+Enter,执行本单元代码,留在本单元
cell行号前的 * ,表示代码正在运行,cell:一对In Out会话被视作一个代码单元,称为cell
命令模式:按ESC进入
编辑模式:按Enter进入
是专门用于开发2D图表(包括3D图表)
使用起来及其简单
以渐进、交互式方式实现数据可视化
可视化是在整个数据挖掘的关键辅助工具,可以清晰的理解数据,从而调整我们的分析方法。
import matplotlib.pyplot as plt
# 1.创建画布
plt.figure(figsize=(20,8), dpi=100)
# 2.绘制图像
x = [1,2,3]
y = [4,5,6]
plt.plot(x, y)
# 3.显示图像
plt.show()
容器层主要由Canvas、Figure、Axes组成。
Canvas是位于最底层的系统层,在绘图的过程中充当画板的角色,即放置画布(Figure)的工具。
Figure是Canvas上方的第一层,也是需要用户来操作的应用层的第一层,在绘图的过程中充当画布的角色。
Axes是应用层的第二层,在绘图的过程中相当于画布上的绘图区的角色。
特点为:
辅助显示层为Axes(绘图区)内的除了根据数据绘制出的图像以外的内容,主要包括Axes外观(facecolor)、边框线(spines)、坐标轴(axis)、坐标轴名称(axis label)、坐标轴刻度(tick)、坐标轴刻度标签(tick label)、网格线(grid)、图例(legend)、标题(title)等内容。
该层的设置可使图像显示更加直观更加容易被用户理解,但又不会对图像产生实质的影响。
图像层指Axes内通过plot、scatter、bar、histogram、pie等函数根据数据绘制出的图像。
总结:
matplotlib.pytplot包含了一系列类似于matlab的画图函数。 它的函数作用于当前图形(figure)的当前坐标系(axes)。
import matplotlib.pyplot as plt
折线图绘制与显示
展现一周的天气,比如从星期一到星期日的天气温度如下
# 1.创建画布(容器层)
plt.figure(figsize=(10, 10))
# 2.绘制折线图(图像层)
plt.plot([1, 2, 3, 4, 5, 6 ,7], [17,17,18,15,11,11,13])
# 3.显示图像
plt.show()
plt.figure(figsize=(), dpi=)
figsize:指定图的长宽
dpi:图像的清晰度
返回fig对象
plt.savefig(path)
# 1.创建画布,并设置画布属性
plt.figure(figsize=(20, 8), dpi=80)
# 2.保存图片到指定路径
plt.savefig("test.png")
注意:plt.show()会释放figure资源,如果在显示图像之后保存图片将只能保存空图片
# 画出温度变化图
# 0.准备x, y坐标的数据
x = range(60)
y_shanghai = [random.uniform(15, 18) for i in x]
# 1.创建画布
plt.figure(figsize=(20, 8), dpi=80)
# 2.绘制折线图
plt.plot(x, y_shanghai)
# 3.显示图像
plt.show()
plt.xticks(x, **kwargs)
x:要显示的刻度值
plt.yticks(y, **kwargs)
y:要显示的刻度值
# 增加以下两行代码
# 构造x轴刻度标签
x_ticks_label = ["11点{}分".format(i) for i in x]
# 构造y轴刻度
y_ticks = range(40)
# 修改x,y轴坐标的刻度显示
plt.xticks(x[::5], x_ticks_label[::5])
plt.yticks(y_ticks[::5])
下载中文字体(黑体,看准系统版本)
下载 SimHei 字体(或者其他的支持中文显示的字体也行)
安装字体
linux下:拷贝字体到 usr/share/fonts 下:
sudo cp ~/SimHei.ttf /usr/share/fonts/SimHei.ttf
windows和mac下:双击安装
删除~/.matplotlib中的缓存文件
cd ~/.matplotlib
rm -r *
修改配置文件matplotlibrc
vi ~/.matplotlib/matplotlibrc
将文件内容修改为:
font.family : sans-serif
font.sans-serif : SimHei
axes.unicode_minus : False
为了更加清楚地观察图形对应的值
plt.grid(True, linestyle='--', alpha=0.5)
添加x轴、y轴描述信息及标题
plt.xlabel("时间")
plt.ylabel("温度")
plt.title("中午11点0分到12点之间的温度变化图示")
# 增加北京的温度数据
y_beijing = [random.uniform(1, 3) for i in x]
# 绘制折线图
plt.plot(x, y_shanghai, label="上海")
# 使用多次plot可以画多个折线
plt.plot(x, y_beijing, color='r', linestyle='--', label="北京")
# 显示图例
plt.legend(loc="best")
注意:如果只在plt.plot()中设置label还不能最终显示出图例,还需要通过plt.legend()将图例显示出来。
plt.legend(loc="best")
import matplotlib.pyplot as plt
import random
# 多次plot
# 0.创建数据
x = range(60)
y_shanghai = [random.uniform(15,18) for i in x]
y_beijing = [random.uniform(-5, 5) for i in x]
# 1.创建画布
plt.figure(figsize=(20, 8), dpi=100)
# 2.绘制图
plt.plot(x, y_shanghai, label="上海", color="r", linestyle="--")
plt.plot(x, y_beijing, label="北京")
# 2.1 添加x,y轴的刻度
x_labels_ticks = ["11点{}分".format(i) for i in x]
y_labels_ticks = range(-10, 30)
plt.xticks(x[::5], x_labels_ticks[::5])
plt.yticks(y_labels_ticks[::5])
# 2.2 添加网格线
plt.grid(linestyle="--", alpha=0.5)
# 2.3 添加描述信息
plt.xlabel("时间", fontsize=16)
plt.ylabel("温度", fontsize=16)
plt.title("某城市11点-12点温度变化", fontsize=20)
# 2.4 增加图例
plt.legend(loc="best")
# 3.显示
plt.show()
可以通过subplots函数实现(旧的版本中有subplot,使用起来不方便),推荐subplots函数
matplotlib.pyplot.subplots(nrows=1, ncols=1, **fig_kw) 创建一个带有多个axes(坐标系/绘图区)的图
Parameters:
nrows, ncols : int, optional, default: 1, Number of rows/columns of the subplot grid.
**fig_kw : All additional keyword arguments are passed to the figure() call.
Returns:
fig : 图对象
ax :
设置标题等方法不同:
set_xticks
set_yticks
set_xlabel
set_ylabel
注意:plt.函数名()相当于面向过程的画图方法,axes.set_方法名()相当于面向对象的画图方法。
# 需求:画出某城市11点到12点1小时内每分钟的温度变化折线图,温度范围在15度~18度
# 多个axes
# 0.构造数据
x = range(60)
y_shanghai = [random.uniform(15, 18) for i in x]
y_beijing = [random.uniform(1, 14) for i in x]
# 1.创建画布
# plt.figure(figsize=(20, 8))
fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(20, 8), dpi=100)
# 2.图像绘制
# plt.plot(x, y_shanghai, label="上海")
# plt.plot(x, y_beijing, label="北京", linestyle="--", color="r")
axes[0].plot(x, y_shanghai, label="上海")
axes[1].plot(x, y_beijing, label="北京", linestyle="--", color="r")
# 2.1 添加x,y轴刻度
x_ticks_label = ["11点{}分".format(i) for i in x]
y_ticks = range(40)
# plt.xticks(x[::5], x_ticks_label[::5])
# plt.yticks(y_ticks[::5])
axes[0].set_xticks(x[::5])
axes[0].set_yticks(y_ticks[::5])
axes[0].set_xticklabels(x_ticks_label[::5])
axes[1].set_xticks(x[::5])
axes[1].set_yticks(y_ticks[::5])
axes[1].set_xticklabels(x_ticks_label[::5])
# 2.2 添加网格显示
# plt.grid(True, linestyle="--", alpha=0.5)
axes[0].grid(True, linestyle="--", alpha=0.5)
axes[1].grid(True, linestyle="--", alpha=0.5)
# 2.3 添加x,y轴描述和标题
# plt.xlabel("时间")
# plt.ylabel("温度")
# plt.title("中午11点--12点温度变化图", fontsize=25)
axes[0].set_xlabel("时间")
axes[0].set_ylabel("温度")
axes[0].set_title("上海中午11点--12点温度变化图", fontsize=25)
axes[1].set_xlabel("时间")
axes[1].set_ylabel("温度")
axes[1].set_title("北京中午11点--12点温度变化图", fontsize=25)
# 2.4 显示图例
# plt.legend(loc=0)
axes[0].legend(loc=0)
axes[1].legend(loc=0)
# 3.显示
plt.show()
画各种数学函数图像
import matplotlib.pyplot as plt
import numpy as np
# 0.准备数据
x = np.linspace(-10, 10, 1000)
y = np.sin(x)
# 1.创建画布
plt.figure(figsize=(20, 8), dpi=100)
# 2.绘制函数图像
plt.plot(x, y)
# 2.1 添加网格显示
plt.grid()
# 3.显示图像
plt.show()
折线图:以折线的上升或下降来表示统计数量的增减变化的统计图
特点:能够显示数据的变化趋势,反映事物的变化情况。(变化)
api:plt.plot(x, y)
api:plt.scatter(x, y)
api:plt.bar(x,y, width, align='center', **kwargs)
import matplotlib.pyplot as plt
# 创建画布
plt.figure(figsize=(20,8))
# 绘制图形
movie_names = ["雷神","正义联盟","诸神黄昏","77天"]
y = [553,884,323,565]
# 先构建X轴
x = range(len(movie_names))
# 设置X的刻度
plt.xticks(x,movie_names)
plt.bar(x,y,width=0.5,color=['r','y','b','g'])
# 显示图形
plt.show()
api:matplotlib.pyplot.hist(x, bins=None)
import matplotlib.pyplot as plt
import random
# 均匀分布
x = np.random.uniform(-10,10,10000000)
# 创建画布
plt.figure(figsize=(20,8),dpi=100)
# 绘制直方图
plt.hist(x,bins=1000) # bins 为分成的区间个数
# 显示图像
plt.show()
api:plt.pie(x, labels=,autopct=,colors)
x:数量,自动算百分比
labels:每部分名称
autopct:占比显示指定%1.2f%%
colors:每部分颜色
Numpy(Numerical Python)是一个开源的Python科学计算库,用于快速处理任意维度的数组。
Numpy支持常见的数组和矩阵操作。对于同样的数值计算任务,使用Numpy比直接使用Python要简洁的多。
Numpy使用ndarray对象来处理多维数组,该对象是一个快速而灵活的大数据容器。
NumPy provides an N-dimensional array type, the ndarray, which describes a collection of “items” of the same type.
NumPy提供了一个N维数组类型ndarray,它描述了相同类型的“items”的集合
用ndarray进行存储:
import numpy as np
# 创建ndarray
score = np.array([[80, 89, 86, 67, 79],
[78, 97, 89, 67, 81],
[90, 94, 78, 67, 74],
[91, 91, 90, 67, 69],
[76, 87, 75, 67, 86],
[70, 79, 84, 67, 84],
[94, 92, 93, 67, 64],
[86, 85, 83, 67, 80]])
score
返回结果:
array([[80, 89, 86, 67, 79],
[78, 97, 89, 67, 81],
[90, 94, 78, 67, 74],
[91, 91, 90, 67, 69],
[76, 87, 75, 67, 86],
[70, 79, 84, 67, 84],
[94, 92, 93, 67, 64],
[86, 85, 83, 67, 80]])
import random
import time
import numpy as np
a = []
for i in range(100000000):
a.append(random.random())
# 通过%time魔法方法, 查看当前行的代码运行一次所花费的时间
%time sum1=sum(a)
b=np.array(a)
%time sum2=np.sum(b)
可以看出ndarray的计算速度要快很多,节约了时间。
机器学习的最大特点就是大量的数据运算,那么如果没有一个快速的解决方案,那可能现在python也在机器学习领域达不到好的效果。
Numpy专门针对ndarray的操作和运算进行了设计,所以数组的存储效率和输入输出性能远优于Python中的嵌套列表,数组越大,Numpy的优势就越明显。
ndarray在存储数据的时候,数据与数据的地址都是连续的,这样就给使得批量操作数组元素时速度更快。
这是因为ndarray中的所有元素的类型都是相同的,而Python列表中的元素类型是任意的,所以ndarray在存储元素时内存可以连续,而python原生list就只能通过寻址方式找到下一个元素,这虽然也导致了在通用性能方面Numpy的ndarray不及Python原生list,但在科学计算中,Numpy的ndarray就可以省掉很多循环语句,代码使用方面比Python原生list简单的多。
Numpy底层使用C语言编写,内部解除了GIL(全局解释器锁),其对数组的操作速度不受Python解释器的限制,所以,其效率远高于纯Python代码。
数组属性反映了数组本身固有的信息。
ndarray.shape 数组维度的元组
ndarray.ndim 数组维数
ndarray.size 数组中的元素数量
ndarray.itemsize 一个数组元素的长度(字节)
ndarray.dtype 数组元素的类型
# 创建不同形状的数组
>>> a = np.array([[1,2,3],[4,5,6]])
>>> b = np.array([1,2,3,4])
>>> c = np.array([[[1,2,3],[4,5,6]],[[1,2,3],[4,5,6]]])
>>> a.shape
>>> b.shape
>>> c.shape
(2, 3) # 二维数组
(4,) # 一维数组
(2, 2, 3) # 三维数组
>>> type(score.dtype)
dtype是numpy.dtype类型,先看看对于数组来说都有哪些类型
创建数组的时候指定类型
>>> a = np.array([[1, 2, 3],[4, 5, 6]], dtype=np.float32)
>>> a.dtype
dtype('float32')
>>> arr = np.array(['python', 'tensorflow', 'scikit-learn', 'numpy'], dtype = np.string_)
>>> arr
array([b'python', b'tensorflow', b'scikit-learn', b'numpy'], dtype='|S12')
注意:若不指定,整数默认int64,小数默认float64
生成0和1的数组
>>> zero = np.zeros([3, 4])
array([[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.]])
生成方式
a = np.array([[1,2,3],[4,5,6]])
# 从现有的数组当中创建
a1 = np.array(a)
# 相当于索引的形式,并没有真正的创建一个新的
a2 = np.asarray(a)
np.linspace (start, stop, num, endpoint)
生成等间隔的序列
start 序列的起始值
stop 序列的终止值,
num 要生成的等间隔样例数量,默认为50
endpoint 序列中是否包含stop值,默认为ture
# 生成等间隔的数组
np.linspace(0, 100, 11)
# 返回结果
array([ 0., 10., 20., 30., 40., 50., 60., 70., 80., 90., 100.])
其它的还有
numpy.arange(start,stop, step, dtype)
numpy.logspace(start,stop, num)
np.arange(10, 50, 2)
返回结果:
array([10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42,
44, 46, 48])
# 生成10^x
np.logspace(0, 2, 3)
返回结果:
array([ 1., 10., 100.])
使用模块介绍
np.random模块
np.random.rand(d0, d1, ..., dn)
返回[0.0,1.0)内的一组均匀分布的数。
np.random.uniform(low=0.0, high=1.0, size=None)
功能:从一个均匀分布[low,high)中随机采样,注意定义域是左闭右开,即包含low,不包含high.
参数介绍:
low: 采样下界,float类型,默认值为0;
high: 采样上界,float类型,默认值为1;
size: 输出样本数目,为int或元组(tuple)类型,例如,size=(m,n,k), 则输出mnk个样本,缺省时输出1个值。
返回值:ndarray类型,其形状和参数size中描述一致。
np.random.randint(low, high=None, size=None, dtype='l')
从一个均匀分布中随机采样,生成一个整数或N维整数数组,取数范围:若high不为None时,取[low,high)之间随机整数,否则取值[0,low)之间随机整数。
# 生成均匀分布的随机数
x1 = np.random.uniform(-1, 1, 100000000)
返回结果:
array([ 0.22411206, 0.31414671, 0.85655613, ..., -0.92972446,
0.95985223, 0.23197723])
画图看分布状况:
import matplotlib.pyplot as plt
# 生成均匀分布的随机数
x1 = np.random.uniform(-1, 1, 100000000)
# 画图看分布状况
# 1)创建画布
plt.figure(figsize=(10, 10), dpi=100)
# 2)绘制直方图
plt.hist(x=x1, bins=1000) # x代表要使用的数据,bins表示要划分区间数
# 3)显示图像
plt.show()
正态分布是一种概率分布。正态分布是具有两个参数μ和σ的连续型随机变量的分布,第一参数μ是服从正态分布的随机变量的均值,第二个参数σ是此随机变量的方差,所以正态分布记作N(μ,σ )。
正态分布特点
μ决定了其位置,其标准差σ决定了分布的幅度。当μ = 0,σ = 1时的正态分布是标准正态分布。
方差
是在概率论和统计方差衡量一组数据时离散程度的度量
其中M为平均值,n为数据总个数,S为标准差,S2可以理解一个整体为方差
np.random.randn(d0, d1, …, dn)
功能:从标准正态分布中返回一个或多个样本值
np.random.normal(loc=0.0, scale=1.0, size=None)
loc:float
此概率分布的均值(对应着整个分布的中心centre)
scale:float
此概率分布的标准差(对应于分布的宽度,scale越大越矮胖,scale越小,越瘦高)
size:int or tuple of ints
输出的shape,默认为None,只输出一个值
np.random.standard_normal(size=None)
返回指定形状的标准正态分布的数组。
x2 = np.random.normal(1.75, 1, 100000000)
返回结果:
array([2.90646763, 1.46737886, 2.21799024, ..., 1.56047411, 1.87969135,
0.9028096 ])
import matplotlib.pyplot as plt
import random
# 生成均匀分布的随机数
x2 = np.random.normal(1.75, 1, 100000000)
# 画图看分布状况
# 1)创建画布
plt.figure(figsize=(20, 10), dpi=100)
# 2)绘制直方图
plt.hist(x2, 1000)
# 3)显示图像
plt.show()
案例:随机生成8只股票2周的交易日涨幅数据
import random
# 随机生成8行10列的数组
stock_change = np.random.standard_normal((8,10))
stock_change
array([[ 0.14401682, -1.48963539, -0.8895709 , -0.34989962, -0.97773321,
-0.74861063, 0.26386878, 1.27982551, 1.12473295, 0.18776722],
[ 0.27111159, -1.28547271, -0.85684537, 1.74141715, -1.73204494,
1.52240873, -0.46314502, -0.60541425, 1.00799328, 0.70257848],
[-1.43352805, 0.12857923, -0.65452426, -0.42321317, -0.48861617,
0.43218611, -0.92345367, 0.72922499, -0.6405581 , 0.12503792],
[ 0.35952641, -1.24174139, 0.75046079, 0.13072002, 0.48565156,
-0.26730213, 0.32302435, -0.72131556, -0.995412 , -1.36096473],
[-0.02209019, -0.35493271, -0.69888324, -0.38827834, 0.65855429,
-0.75036987, -0.68924239, 1.63248018, 0.3047486 , -0.51231325],
[ 1.86970181, -0.29139264, -0.90990551, -0.65727445, 0.18708323,
-0.49455804, 0.12187795, 0.78919161, 0.99579209, -0.14336594],
[ 0.18919138, -1.00346025, -0.71156217, -1.06322924, -1.90883858,
-1.14991256, -1.9027262 , -0.60638635, 0.45175841, 1.99453615],
[ 0.32861702, 0.7616844 , -2.0241717 , -0.12842078, -2.0839974 ,
-0.69092221, -1.37096095, -1.05165983, -0.82271123, 0.69256602]])
-切片方法 每个维度用冒号索引进行切片[起:止:步长],多少维度就用多少冒号索引
# stock_changek[,] 切片 ,左边为行索引 右侧为列索引,
stock_change[0,0]
0.14401682
stock_change[0,0] =10
stock_change
np.unique()
temp = np.array([[1, 2, 3, 4],[3, 4, 5, 6]])
>>> np.unique(temp)
array([1, 2, 3, 4, 5, 6])
# 重新生成8只股票10个交易日的涨跌幅数据
>>> stock_change = np.random.normal(0, 1, (8, 10))
>>> stock_change = stock_change[0:5, 0:5]
# 逻辑判断, 如果涨跌幅大于0.5就标记为True 否则为False
>>> stock_change > 0.5
array([[ True, False, False, True, False],
[ True, True, False, False, False],
[ True, False, True, False, True],
[False, True, False, False, False],
[False, False, False, True, True]])
# BOOL赋值, 将满足条件的设置为指定的值-布尔索引
>>> stock_change[stock_change > 0.5] = 1
array([[ 1. , -0.72404879, -1.33045773, 1. , 0.3869043 ],
[ 1. , 1. , 0.20815446, -1.67860823, 0.06612823],
[ 1. , 0.42753488, 1. , -0.24375089, 1. ],
[-0.971945 , 1. , -0.95444661, -0.2602084 , -0.48736497],
[-0.32183056, -0.92544956, -0.42126604, 1. , 1. ]])
np.all()
# 判断stock_change[0:2, 0:5]是否全是上涨的
>>> np.all(stock_change[0:2, 0:5] > 0)
False
np.any()
# 判断前5只股票这段期间是否有上涨的
>>> np.any(stock_change[0:5, :] > 0 )
True
通过使用np.where能够进行更加复杂的运算
np.where()
# 判断前四个股票前四天的涨跌幅 大于0的置为1,否则为0
temp = stock_change[:4, :4]
np.where(temp > 0, 1, 0)
复合逻辑需要结合np.logical_and和np.logical_or使用
# 判断前四个股票前四天的涨跌幅 大于0.5并且小于1的,换为1,否则为0
# 判断前四个股票前四天的涨跌幅 大于0.5或者小于-0.5的,换为1,否则为0
np.where(np.logical_and(temp > 0.5, temp < 1), 1, 0)
np.where(np.logical_or(temp > 0.5, temp < -0.5), 1, 0)
axis 轴的取值并不一定,Numpy中不同的API轴的值都不一样,在这里,axis 0代表列, axis 1代表行去进行统计
# 接下来对于这4只股票的4天数据,进行一些统计运算
# 指定行 去统计
print("前四只股票前四天的最大涨幅{}".format(np.max(temp, axis=1)))
# 使用min, std, mean
print("前四只股票前四天的最大跌幅{}".format(np.min(temp, axis=1)))
print("前四只股票前四天的波动程度{}".format(np.std(temp, axis=1)))
print("前四只股票前四天的平均涨跌幅{}".format(np.mean(temp, axis=1)))
统计出哪一只股票在某个交易日的涨幅最大或者最小
np.argmax(temp, axis=)
np.argmin(temp, axis=)
# 获取股票指定哪一天的涨幅最大
print("前四只股票前四天内涨幅最大{}".format(np.argmax(temp, axis=1)))
print("前四天一天内涨幅最大的股票{}".format(np.argmax(temp, axis=0)))
执行 broadcast 的前提在于,两个 ndarray 执行的是 element-wise的运算,Broadcast机制的功能是为了方便不同形状的ndarray(numpy库的核心数据结构)进行数学运算。
当操作两个数组时,numpy会逐个比较它们的shape(构成的元组tuple),只有在下述情况下,两个数组才能够进行数组与数组的运算。
Image (3d array): 256 x 256 x 3
Scale (1d array): 3
Result (3d array): 256 x 256 x 3
A (4d array): 9 x 1 x 7 x 1
B (3d array): 8 x 1 x 5
Result (4d array): 9 x 8 x 7 x 5
A (2d array): 5 x 4
B (1d array): 1
Result (2d array): 5 x 4
A (3d array): 15 x 3 x 5
B (3d array): 15 x 1 x 1
Result (3d array): 15 x 3 x 5
如果是下面这样,则不匹配:
A (1d array): 10
B (1d array): 12
A (2d array): 2 x 1
B (3d array): 8 x 4 x 3`
>>> a = np.array([[80, 86],
[82, 80],
[85, 78],
[90, 90],
[86, 82],
[82, 90],
[78, 80],
[92, 94]])
>>> b = np.array([[0.7], [0.3]])
>>> np.matmul(a, b)
array([[81.8],
[81.4],
[82.9],
[90. ],
[84.8],
[84.4],
[78.6],
[92.6]])
>>> np.dot(a,b)
array([[81.8],
[81.4],
[82.9],
[90. ],
[84.8],
[84.4],
[78.6],
[92.6]])
np.matmul和np.dot的区别
二者都是矩阵乘法。 np.matmul中禁止矩阵与标量的乘法。 在矢量乘矢量的內积运算中,np.matmul与np.dot没有区别。
案例:获取两周内8支股票走势
import numpy as np
import pandas as pd
stock_change = np.random.standard_normal((8,10))
stock_change
array([[-0.05754788, 0.21029898, -0.03265957, 1.30351707, 0.33197182,
1.56983804, -0.23480505, -1.65475427, 0.46816427, -0.48388722],
[ 0.41802156, -0.27505386, -1.54310245, -0.25989823, -0.39275176,
-0.25082766, -1.10979654, -0.47782569, 0.41750598, -0.72252277],
[ 0.97766123, 0.97637506, 1.01732863, 0.2499813 , 0.06167437,
0.13933275, -1.84336271, 1.47588191, 0.14630719, 0.35324661],
[ 1.59041433, -1.08861395, 0.30696252, -0.58626648, 1.78051606,
0.07977819, -0.47066406, -1.60293909, -0.14450208, 0.21785362],
[ 0.95166164, 0.33578104, -1.25532418, -0.45929209, -0.42486285,
-0.34487713, 0.00922157, 1.18608095, 0.27595473, 0.63853717],
[-0.07249857, -1.20066942, 0.64326827, -0.13906129, -2.04712474,
-0.12335355, 0.3131091 , 1.22563968, 0.53614054, -1.62965967],
[ 0.37837798, -2.08070101, 0.58598907, -0.45026638, -0.35867323,
0.18418201, 0.18236871, -0.05144433, -1.45733102, -1.70084381],
[ 0.24184604, -0.37030245, 1.22672516, 0.72156162, -0.71482026,
-0.75437147, -0.62633426, -0.31137122, -0.56577178, 0.76745035]])
使用pandas的数据结构
data = pd.DataFrame(stock_change)
data
codes = ['股票'+str(i) for i in range(8)]
codes
# 生成日期数据 date_range('开始日期',periods=天数,freq='B'-是否跳过周末)
date = pd.date_range('20200101',periods=10,freq='B')
date
# 设置行列名字
data = pd.DataFrame(stock_change,index=codes,columns=date)
data
DataFrame对象既有行索引,又有列索引
# 生成新的index列表
new_index = ['股票_'+str(i) for i in range(8)]
# 替换旧索引 ,必须整体全部修改
data.index = new_index
set_index(keys, drop=True)
df = pd.DataFrame({'month': [1, 4, 7, 10],
'year': [2012, 2014, 2013, 2014],
'sale':[55, 40, 84, 31]})
month sale year
0 1 55 2012
1 4 40 2014
2 7 84 2013
3 10 31 2014
以月份设置新的索引
df.set_index('month')
sale year
month
1 55 2012
4 40 2014
7 84 2013
10 31 2014
设置多个索引,以年和月份
df.set_index(['year', 'month'])
sale
year month
2012 1 55
2014 4 40
2013 7 84
2014 10 31
注:通过刚才的设置,这样DataFrame就变成了一个具有MultiIndex的DataFrame。
打印刚才的df的行索引结果
df.index
MultiIndex(levels=[[2012, 2013, 2014], [1, 4, 7, 10]],
labels=[[0, 2, 1, 2], [0, 1, 2, 3]],
names=['year', 'month'])
多级或分层索引对象。
df.index.names
FrozenList(['year', 'month'])
df.index.levels
FrozenList([[1, 2], [1, 4, 7, 10]])
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
Dimensions: 4 (items) x 3 (major_axis) x 2 (minor_axis)
Items axis: A to D
Major_axis axis: 2013-01-01 00:00:00 to 2013-01-03 00:00:00
Minor_axis axis: first to second
查看panel数据:
p[:,:,"first"]
p["B",:,:]
注:Pandas从版本0.20.0开始弃用:推荐的用于表示3D数据的方法是通过DataFrame上的MultiIndex方法
series结构只有行索引
创建series
通过已有数据创建
pd.Series(np.arange(10))
pd.Series([6.7,5.6,3,10,2], index=[1,2,3,4,5])
pd.Series({'red':100, ''blue':200, 'green': 500, 'yellow':1000})
# 读取文件
data = pd.read_csv("./data/stock_day.csv")
# 删除一些列
data = data.drop(["ma5","ma10","ma20","v_ma5","v_ma10","v_ma20"], axis=1)
# 通过[]索引
data['close'].head() # Series
data['close']['2018-02-22'] # 先列后行
# loc索引 通过索引名字,先行后列
data.loc['2018-02-23','close':'low'] # Series
# iloc 通过索引下标
data.iloc[2,2:4]
获取行第1天到第4天,['open', 'close', 'high', 'low']这个四个指标的结果
# 使用ix进行下表和名称组合做引
data.ix[0: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'])]
open close high low
2018-02-27 23.53 24.16 25.88 23.53
2018-02-26 22.80 23.53 23.78 22.80
2018-02-23 22.88 22.82 23.37 22.71
2018-02-22 22.25 22.28 22.76 22.02
对DataFrame当中的close列进行重新赋值为1
# 直接修改原来的值
data['close'] = 1
# 或者
data.close = 1
排序有两种形式,一种对于索引进行排序,一种对于内容进行排序
# 按照涨跌幅大小进行排序 , 使用ascending指定按照大小排序
data = data.sort_values(by='p_change', ascending=False).head()
open high close low volume price_change p_change turnover
2015-08-28 15.40 16.46 16.46 15.00 117827.60 1.50 10.03 4.03
2015-05-21 27.50 28.22 28.22 26.50 121190.11 2.57 10.02 4.15
2016-12-22 18.50 20.42 20.42 18.45 150470.83 1.86 10.02 3.77
2015-08-04 16.20 17.35 17.35 15.80 94292.63 1.58 10.02 3.23
2016-07-07 18.66 18.66 18.66 18.41 48756.55 1.70 10.02 1.67
# 按照过个键进行排序
data = data.sort_values(by=['open', 'high'])
open high close low volume price_change p_change turnover
2015-06-15 34.99 34.99 31.69 31.69 199369.53 -3.52 -10.00 6.82
2015-06-12 34.69 35.98 35.21 34.01 159825.88 0.82 2.38 5.47
2015-06-10 34.10 36.35 33.85 32.23 269033.12 0.51 1.53 9.21
2017-11-01 33.85 34.34 33.83 33.10 232325.30 -0.61 -1.77 5.81
2015-06-11 33.17 34.98 34.39 32.51 173075.73 0.54 1.59 5.92
# 对索引进行排序
data.sort_index()
open high close low volume price_change p_change turnover
2015-03-02 12.25 12.67 12.52 12.20 96291.73 0.32 2.62 3.30
2015-03-03 12.52 13.06 12.70 12.52 139071.61 0.18 1.44 4.76
2015-03-04 12.80 12.92 12.90 12.61 67075.44 0.20 1.57 2.30
2015-03-05 12.88 13.45 13.16 12.87 93180.39 0.26 2.02 3.19
2015-03-06 13.17 14.48 14.28 13.13 179831.72 1.12 8.51 6.16
# 加add ,减sub,乘mul,除div
data['low'].add(10).head()
data['high'].sub(data['close'])
<、 >、|、 &
data['p_change'] > 2
2018-02-27 True
2018-02-26 True
2018-02-23 True
2018-02-22 False
2018-02-14 True
# 逻辑判断的结果可以作为筛选的依据
data[data['p_change'] > 2]
pen high close low volume price_change p_change turnover my_price_change
2018-02-27 23.53 25.88 24.16 23.53 95578.03 0.63 2.68 2.39 0.63
2018-02-26 22.80 23.78 23.53 22.80 60985.11 0.69 3.02 1.53 0.73
2018-02-23 22.88 23.37 22.82 22.71 52914.01 0.54 2.42 1.32 -0.06
2018-02-14 21.49 21.99 21.92 21.48 23331.04 0.44 2.05 0.58 0.43
2018-02-12 20.70 21.40 21.19 20.63 32445.39 0.82 4.03 0.81 0.49
完成一个多个逻辑判断, 筛选p_change > 2并且open > 15
data[(data['p_change'] > 2) & (data['open'] > 15)]
open high close low volume price_change p_change turnover my_price_change
2017-11-14 28.00 29.89 29.34 27.68 243773.23 1.10 3.90 6.10 1.34
2017-10-31 32.62 35.22 34.44 32.20 361660.88 2.38 7.42 9.05 1.82
2017-10-27 31.45 33.20 33.11 31.45 333824.31 0.70 2.16 8.35 1.66
2017-10-26 29.30 32.70 32.41 28.92 501915.41 2.68 9.01 12.56 3.11
逻辑运算函数
通过query使得刚才的过程更加方便简单
data.query("p_change > 2 & turnover > 15")
isin(values)
例如判断'turnover'是否为4.19, 2.39
# 可以指定值进行一个判断,从而进行筛选操作
data[data['turnover'].isin([4.19, 2.39])]
open high close low volume price_change p_change turnover my_price_change
2018-02-27 23.53 25.88 24.16 23.53 95578.03 0.63 2.68 2.39 0.63
2017-07-25 23.07 24.20 23.70 22.64 167489.48 0.67 2.91 4.19 0.63
2016-09-28 19.88 20.98 20.86 19.71 95580.75 0.98 4.93 2.39 0.98
2015-04-07 16.54 17.98 17.54 16.50 122471.85 0.88 5.28 4.19 1.00
data.describe()
综合分析: 能够直接得出很多统计结果,count, mean, std, min, max 等
min(最小值), max(最大值), mean(平均值), median(中位数), var(方差), std(标准差),mode(众数)
# 使用统计函数:0 代表列求结果, 1 代表行求统计结果
data.max(0)
open 34.99
high 36.35
close 35.21
low 34.01
volume 501915.41
price_change 3.03
p_change 10.03
turnover 12.56
my_price_change 3.41
dtype: float64
median():中位数
中位数为将数据从小到大排列,在最中间的那个数为中位数。如果没有中间数,取中间两个数的平均值。
df = pd.DataFrame({'COL1' : [2,3,4,5,4,2],
'COL2' : [0,1,2,3,4,2]})
df.median()
COL1 3.5
COL2 2.0
dtype: float64
idxmax()、idxmin()
# 求出最大值的位置
data.idxmax(axis=0)
open 2015-06-15
high 2015-06-10
close 2015-06-12
low 2015-06-12
volume 2017-10-26
price_change 2015-06-09
p_change 2015-08-28
turnover 2017-10-26
my_price_change 2015-07-10
dtype: object
# 求出最小值的位置
data.idxmin(axis=0)
open 2015-03-02
high 2015-03-02
close 2015-09-02
low 2015-03-02
volume 2016-07-06
price_change 2015-06-15
p_change 2015-09-01
turnover 2016-07-06
my_price_change 2015-06-15
dtype: object
data.head()
temp = data.sort_index(ascending=True)
# 统计累计求和值
res = temp['price_change'].cumsum()
# 绘制折线图
import matplotlib.pyplot as plt
res.plot()
plt.title('股票累计变化图')
plt.show()
# 自定义函数
def fun_1(x):
return x.max()-x.min()
# apply(自定义函数名,axis=0即列/1即行)
data[['open','close']].apply(fun_1,axis=0)
或者
data[['open', 'close']].apply(lambda x: x.max() - x.min(), axis=0)
pandas会支持复杂的IO操作,pandas的API支持众多的文件格式,如CSV、SQL、XLS、JSON、HDF5。
read_csv
# 读取文件,并且指定只获取'open', 'close'指标
data = pd.read_csv("./data/stock_day.csv", usecols=['open', 'close'])
open high close
2018-02-27 23.53 25.88 24.16
2018-02-26 22.80 23.78 23.53
2018-02-23 22.88 23.37 22.82
2018-02-22 22.25 22.76 22.28
2018-02-14 21.49 21.99 21.92
to_csv
ead_hdf与to_hdf
HDF5文件的读取和存储需要指定一个键,值为要存储的DataFrame
从h5文件当中读取数据
向h5文件当中写入数据
案例
读取文件
day_eps_ttm = pd.read_hdf("./data/stock_data/day/day_eps_ttm.h5")
如果读取的时候出现以下错误
需要安装安装tables模块避免不能读取HDF5文件
pip install tables
day_eps_ttm.to_hdf("./data/test.h5", key="day_eps_ttm")
再次读取的时候, 需要指定键的名字
new_eps = pd.read_hdf("./data/test.h5", key="day_eps_ttm")
read_json
read_josn 案例
数据介绍
这里使用一个新闻标题讽刺数据集,格式为json。is_sarcastic:1讽刺的,否则为0;headline:新闻报道的标题;article_link:链接到原始新闻文章。存储格式为:
{"article_link": "https://www.huffingtonpost.com/entry/versace-black-code_us_5861fbefe4b0de3a08f600d5", "headline": "former versace store clerk sues over secret 'black code' for minority shoppers", "is_sarcastic": 0}
{"article_link": "https://www.huffingtonpost.com/entry/roseanne-revival-review_us_5ab3a497e4b054d118e04365", "headlin
读取
orient指定存储的json格式,lines指定按照行去变成一个样本
json_read = pd.read_json("./data/Sarcasm_Headlines_Dataset.json", orient="records", lines=True)
to_json 案例
json_read.to_json("./data/test.json", orient='records')
结果
[{"article_link":"https:\/\/www.huffingtonpost.com\/entry\/versace-black-code_us_5861fbefe4b0de3a08f600d5","headline":"former versace store clerk sues over secret 'black code' for minority shoppers","is_sarcastic":0},{"article_link":"https:\/\/www.huffingtonpost.com\/entry\/roseanne-revival-review_us_5ab3a497e4b054d118e04365","headline":"the 'roseanne' revival catches up to our thorny political mood, for better and worse","is_sarcastic":0},{"article_link":"https:\/\/local.theonion.com\/mom-starting-to-fear-son-s-web-series-closest-thing-she-1819576697","headline":"mom starting to fear son's web series closest thing she will have to grandchild","is_sarcastic":1},{"article_link":"https:\/\/politics.theonion.com\/boehner-just-wants-wife-to-listen-not-come-up-with-alt-1819574302","headline":"boehner just wants wife to listen, not come up with alternative debt-reduction ideas","is_sarcastic":1},{"article_link":"https:\/\/www.huffingtonpost.com\/entry\/jk-rowling-wishes-snape-happy-birthday_us_569117c4e4b0cad15e64fdcb","headline":"j.k. rowling wishes snape happy birthday in the most magical way","is_sarcastic":0},{"article_link":"https:\/\/www.huffingtonpost.com\/entry\/advancing-the-worlds-women_b_6810038.html","headline":"advancing the world's women","is_sarcastic":0},....]
修改lines参数为True
json_read.to_json("./data/test.json", orient='records', lines=True)
结果
{"article_link":"https:\/\/www.huffingtonpost.com\/entry\/versace-black-code_us_5861fbefe4b0de3a08f600d5","headline":"former versace store clerk sues over secret 'black code' for minority shoppers","is_sarcastic":0}
{"article_link":"https:\/\/www.huffingtonpost.com\/entry\/roseanne-revival-review_us_5ab3a497e4b054d118e04365","headline":"the 'roseanne' revival catches up to our thorny political mood, for better and worse","is_sarcastic":0}
{"article_link":"https:\/\/local.theonion.com\/mom-starting-to-fear-son-s-web-series-closest-thing-she-1819576697","headline":"mom starting to fear son's web series closest thing she will have to grandchild","is_sarcastic":1}
{"article_link":"https:\/\/politics.theonion.com\/boehner-just-wants-wife-to-listen-not-come-up-with-alt-1819574302","headline":"boehner just wants wife to listen, not come up with alternative debt-reduction ideas","is_sarcastic":1}
{"article_link":"https:\/\/www.huffingtonpost.com\/entry\/jk-rowling-wishes-snape-happy-birthday_us_569117c4e4b0cad15e64fdcb","headline":"j.k. rowling wishes snape happy birthday in the most magical way","is_sarcastic":0}...
判断数据是否为NaN:
处理方式:
存在缺失值nan,并且是np.nan:
不是缺失值nan,有默认标记的
案例
import pandas as pd
import numpy as np
# 缺失值处理
data = pd.read_csv('/home/python/Desktop/test_data/IMDB-Movie-Data.csv')
# 判断是否有缺失
res = pd.isnull(data) # 判断每个元素是否是NaN
# 判断是否有True
np.any(res)
# 判断是否有缺失
res_2 = pd.notnull(data) # 判断每个元素是否不是NaN
np.all(res_2) # 判断是否全为True
# 1.删除缺失值 dropna 删除有缺失的整行,不修改原数据
data.dropna()
# 2.替换/填充缺失值 fillna 填充平均值或者中位数
data.fillna(value=data.mean())
wis = pd.read_csv("https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/breast-cancer-wisconsin.data")
若如下错误:
URLError:
解决办法:
# 全局取消证书验证
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
特殊标记缺失值处理方法:
# 删除
wis = wis.dropna()
连续属性离散化的目的是为了简化数据结构,数据离散化技术可以用来减少给定连续属性值的个数。离散化方法经常作为数据挖掘的工具。
连续属性的离散化就是在连续属性的值域上,将值域划分为若干个离散的区间,最后用不同的符号或整数 值代表落在每个子区间中的属性值。
离散化有很多种方法,这使用一种最简单的方式去操作
这样我们将数据分到了三个区间段,我可以对应的标记为矮、中、高三个类别,最终要处理成一
个"哑变量"矩阵
哑变量(Dummy Variable),又称为虚拟变量、虚设变量或名义变量,从名称上看就知道,它是人为虚设的变量,通常取值为0或1,来反映某个变量的不同属性。
Dummy Coding
import pandas as pd
# 读取数据
data = pd.read_csv('/home/python/Desktop/test_data/stock_day.csv')
data.head()
# 取出p_change列
p_change = data['p_change']
# 进行数据离散化 qcut(离散化的数据,组数,labels=新组名),qcut将数据平均分到指定数量的类别中
res = pd.qcut(p_change,3,labels=['A','B','C'])
res.value_counts() # 统计离散化的各个结果数量
# 指定区间划分
bins = [-100,-7,-3,0,3,7,100]
res3 = pd.cut(p_change,bins)
res3.value_counts() # 统计离散化的各个结果数量
把每个类别生成一个布尔列,这些列中只有一列可以为这个样本取值为1.其又被称为热编码。
pandas.get_dummies(data, prefix=None)
# 得出one-hot编码矩阵
dummies = pd.get_dummies(p_counts, prefix="rise")
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# 读取数据
data = pd.read_csv('/home/python/Desktop/test_data/stock_day.csv')
# 获取p_change列
p_change = data['p_change']
# 离散化
res = pd.qcut(p_change,3)
res.value_counts()
# one-hot编码
res2 = pd.get_dummies(res,prefix='abc')
res2
# 数据集合并 axis=1 按列合并,axis=0按行合并
pd.concat([data,res2],axis=1)
pd.merge(left, right, how=‘inner’, on=None, left_on=None, right_on=None)
内连接
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']})
# 默认内连接
result = pd.merge(left, right, on=['key1', 'key2'])
result = pd.merge(left, right, how='left', on=['key1', 'key2'])
result = pd.merge(left, right, how='right', on=['key1', 'key2'])
result = pd.merge(left, right, how='outer', on=['key1', 'key2'])
交叉表(cross-tabulation, 简称crosstab)是一种用于计算分组频率的特殊透视表.
交叉表是寻找两列之间的关系,按第一列的分组的同时,继续按 第2列分组,并统计个数。
data.head()
# 探究股票涨跌与星期几有关
pd.to_datetime(data.index).weekday # 0为周一
# 添加新一列并赋值
data['week'] = pd.to_datetime(data.index).weekday
data.head()
# 创建新一列记录涨跌,通过np.where 更改True为1,False为0
data['rise'] = np.where(data['p_change']>0,1,0)
data.head()
# 建立交叉表 两列离散数据
temp = pd.crosstab(data['rise'],data['week'])
temp
# 按列求和
sum_date = temp.sum(axis=0)
sum_date
# 计算每周上涨下跌概率 63/125=0.504
res = temp.div(sum_date,axis=1)
res
# 绘制柱状图
res = res.T # 取数据时候,行列位置颠倒,因此先转置
res.plot(kind='bar',stacked=True)
plt.show()
各种电子表格程序和其他数据分析软件中一种常见的数据汇总工具。它根据一个或多个键对数据进行聚合,并根据行和列上的分组键将数据分配到各个矩形区域中。
透视表就是将指定原有DataFrame的列分别作为行索引和列索引,然后对指定的列应用聚集函数(默认情况下式mean函数)。
pivot_table(data,index,colums,values,aggfunc,fill_value,margins,margins_name=)
# 用透视表计算涨跌概率 透视表一般用来分组和聚合
pd.pivot_table(data=data,index='week',values='rise',aggfunc='mean')
DataFrame.groupby(key, as_index=False)
import pandas as pd
import matplotlib.pyplot as plt
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]})
color object price1 price2
0 white pen 5.56 4.75
1 red pencil 4.20 4.12
2 green pencil 1.30 1.60
3 red ashtray 0.56 0.75
4 green pen 2.75 3.15
col.groupby(['color'])['price1'].mean()
col['price1'].groupby(col['color']).mean()
# 分组
col.groupby(['color'],as_index=False)['price1'].mean()
分组数据结构改变
as_index 的默认值为True, 对于聚合输出,返回以组标签作为索引的对象。仅与DataFrame输入相关。as_index = False实际上是“SQL风格”的分组输出。
案例
数据来源
# 导入星巴克店的数据
starbucks = pd.read_csv("./data/starbucks/directory.csv")
starbucks
# 按照国家分组,求出每个国家的星巴克零售店数量
count = starbucks.groupby(['Country']).count()
画图显示结果
count['Brand'].plot(kind='bar', figsize=(20, 8))
plt.show()
# 设置多个索引,set_index()
starbucks.groupby(['Country', 'State/Province']).count()
# %matplotlib inline # 内嵌图像到jupyter中,省略plt.show()
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
file_path = '/home/python/Desktop/test_data/IMDB-Movie-Data.csv'
df = pd.read_csv(file_path)
df
# 评分的平均分
df['Rating'].mean()
6.723199999999999
# 得出导演人数信息
df['Director']
# 导演去重
res = df['Director'].unique()
# np.unique(df['Director'])
# 获取导演数量
res.size
644
# 获取Rating的分布情况
df['Rating'].plot(kind='hist',figsize=(20,8),bins=20)
# 修改直方图的x轴刻度,以最大到最小划分为21个区间
plt.xticks(np.linspace(df['Rating'].min(),df['Rating'].max(),21))
# 添加网格线
plt.grid()
plt.show()
# # 设置刻度的第二种方法
# res = df['Rating'].plot(kind='hist',figsize=(20,8),bins=20)
# plt.xticks(res[1])
# 电影分类gener中每个有多个类别,先获取
df['Genre']
# 遍历获取每个类别并存入列表中
temp_list = list()
temp_list = [i.split(',') for i in df['Genre']]
temp_list
# 数组去重
genre_list = [j for i in temp_list for j in i]
genre_temp = np.unique(genre_list)
genre_temp
# 构建一个记录电影类型数量的容器 Series
genre_s = pd.Series(np.zeros((len(genre_temp),)),index=genre_temp)
genre_s
# 遍历temp_list,出现一次类型,Series中+1
for i in temp_list:
for j in i:
genre_s[j] +=1
genre_s
# 绘制图像
genre_s.plot(kind='bar',figsize=(20,8))
plt.show()
Seaborn其实是在matplotlib的基础上进行了更高级的API封装,从而使得作图更加容易,在大多数情况下使用seaborn就能做出很具有吸引力的图,而使用matplotlib就能制作具有更多特色的图。应该把Seaborn视为matplotlib的补充,而不是替代物。
import numpy as np
import pandas as pd
# from scipy import stats
import matplotlib.pyplot as plt
import seaborn as sns
# %matplotlib inline
# 单变量分布
x1 = np.random.normal(size=1000)
sns.distplot(x1);
x2 = np.random.randint(0, 100, 500)
sns.distplot(x2);
# 直方图
sns.distplot(x1, bins=20, kde=False, rug=True)
# 核密度估计
sns.distplot(x2, hist=False, rug=True)
# 双变量分布
df_obj1 = pd.DataFrame({"x": np.random.randn(500),
"y": np.random.randn(500)})
df_obj2 = pd.DataFrame({"x": np.random.randn(500),
"y": np.random.randint(0, 100, 500)})
# 散布图
sns.jointplot(x="x", y="y", data=df_obj1)
# 二维直方图
sns.jointplot(x="x", y="y", data=df_obj1, kind="hex");
# 核密度估计
sns.jointplot(x="x", y="y", data=df_obj1, kind="kde");
# 数据集中变量间关系可视化
dataset = sns.load_dataset("tips")
#dataset = sns.load_dataset("iris")
sns.pairplot(dataset);
sns.stripplot(x="diet", y="pulse", data=exercise)
sns.swarmplot(x="diet", y="pulse", data=exercise, hue='kind')
# 盒子图
sns.boxplot(x="diet", y="pulse", data=exercise)
#sns.boxplot(x="diet", y="pulse", data=exercise, hue='kind')
# 小提琴图
#sns.violinplot(x="diet", y="pulse", data=exercise)
sns.violinplot(x="diet", y="pulse", data=exercise, hue='kind')
# 柱状图
sns.barplot(x="diet", y="pulse", data=exercise, hue='kind')
# 点图
sns.pointplot(x="diet", y="pulse", data=exercise, hue='kind');