目录
-
- 机器学习库-Matplotlib+Numpy+Pandas
-
-
- 1 Matplotlib基本使用
-
- 1.2 用途
- 1.3 操作指南
- 1.4 常见图形绘制
- 1.5 代码实现
- 2 Numpy基本使用
-
- 2.1 定义
- 2.2 特点
- 2.3 代码实现
- 3 Pandas基本使用
-
- 3.1 定义
- 3.2 特点
- 3.3 操作
- 3.4 Numpy和Pandas区别及联系
- 3.5 Series和Dataframe区别
- 3.6 基本数据操作
- 3.7 DataFram运算
- 3.8 Pandas 画图
- 3.10 缺失值处理
- 3.11 数据离散化
- 3.13 高级处理-交叉表与透视表
- 3.14 高级处理-分组与聚合
-
机器学习库-Matplotlib+Numpy+Pandas
1 Matplotlib基本使用
官方文档:https://matplotlib.org/stable/api/index.html#modules
1.1 特性
- 强大的数据可视化工具和作图库,是主要用于绘制数据图表的Python库,提供了绘制各类可视化图形的命令字库、简单的接口,可以方便用户轻松掌握图形的格式,绘制各类可视化图形。
- 基于Numpy的一套Python包,这个包提供了吩咐的数据绘图工具,主要用于绘制一些统计图形。
- 有一套允许定制各种属性的默认设置,可以控制Matplotlib中的每一个默认属性:图像大小、每英寸点数、线宽、色彩和样式、子图、坐标轴、网格属性、文字和文字属性。
1.2 用途
能将数据进行可视化,更直观的呈现;使数据更加客观、更具说服力;
1.3 操作指南
1.3.1 图像结构
import matplotlib.pyplot as plt# 1.创建画布
plt.figure(figsize=(10, 10), dpi=100)# 2.绘制折线图
plt.plot([1, 2, 3, 4, 5, 6 ,7], [17,17,18,15,11,11,13])# 3.显示图像
plt.show()
1.3.2 中文设置问题
- 解决方案一:
下载中文字体(黑体,看准系统版本)
-
步骤一:下载 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
-
解决方案二:
? 在Python脚本中动态设置matplotlibrc,这样也可以避免由于更改配置文件而造成的麻烦,具体代码如下:
from pylab import mpl # 设置显示中文字体 mpl.rcParams["font.sans-serif"] = ["SimHei"]
有时候,字体更改后,会导致坐标轴中的部分字符无法正常显示,此时需要更改axes.unicode_minus参数:
# 设置正常显示符号 mpl.rcParams["axes.unicode_minus"] = False
1.3.3 图像绘制
plt.plot(x, y, color='r', linestyle='--')
-
刻度显示
-
plt.xticks(刻度值,标签值)
-
plt.yticks(刻度值,标签值)
注意:在传递进去的第一个参数必须是数字,不能是字符串,如果是字符串,需要进行替换操作
-
-
添加网格显示
plt.grid(True, linestyle="--", alpha=0.5)
-
设置标题
plt.title('标题',fontsize=20, pad=20)
-
设置轴标签
plt.xlabel()
plt.ylabel()
-
设置轴取值范围
plt.xlim(a, b)
plt.ylim(a, b)
-
图像保存
-
plt.savefig("路径")
注意:plt.show()会释放figure资源,如果在显示图像之后保存图片将只能保存空图片。
-
-
显示图例
plt.legend(loc="best")
-
多个坐标系显示
-
plt.subplots(nrows=, ncols=, figsize=(20, 8), dpi=100)
# 1.创建画布 fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(20, 8), dpi=100)# 2.绘制图像 axes[1].plot(x, y_beijing, color="r", linestyle="--", label="北京")# 2.1 添加x,y轴刻度 x_ticks_label = ["11点{}分".format(i) for i in x] y_ticks = range(40)# 刻度显示 axes[1].set_xticks(x[::5]) axes[1].set_yticks(y_ticks[::5]) axes[1].set_xticklabels(x_ticks_label[::5])# 2.2 添加网格显示 axes[1].grid(True, linestyle="--", alpha=0.5)# 2.3 添加描述信息 axes[1].set_xlabel("时间") axes[1].set_ylabel("温度") axes[1].set_title("中午11点--12点某城市温度变化图", fontsize=20)# 2.4 图像保存 plt.savefig("./test.png")# 2.5 添加图例 axes[1].legend(loc=0)# 3.图像显示 plt.show()
-
1.4 常见图形绘制
-
1 折线图
- 定义:以折线的上升或下降来表示统计数量的增减变化的统计图
- 特点:能够显示数据的变化趋势,反映事物的变化情况。(变化)
- API:
plt.plot(x, y)
-
2 散点图
-
定义:用两组数据构成多个坐标点,考察坐标点的分布,判断两变量之间是否存在某种关联或总结坐标点的分布模式。
-
特点:判断变量之间是否存在数量关联趋势,展示离群点(分布规律)
-
API:
plt.scatter(x, y)
-
代码实现
# 0.准备数据 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]# 1.创建画布 plt.figure(figsize=(20, 8), dpi=100)# 2.绘制散点图 plt.scatter(x, y)# 3.显示图像 plt.show()
-
-
3 柱状图
-
定义:排列在工作表的列或行中的数据可以绘制到柱状图中。
-
特点:绘制连离散的数据,能够一眼看出各个数据的大小,比较数据之间的差别。(统计/对比)
-
API:
plt.bar(x, width, align='center', color= 'r')
align : 每个柱状图的位置对齐方式{ ‘center’, ‘edge’} 默认: ‘center’
-
代码实现
# 0.准备数据 # 电影名字 movie_name = ['雷神3:诸神黄昏','正义联盟','东方快车谋杀案','寻梦环游记','全球风暴','降魔传','追捕','七十七天','密战','狂兽','其它'] # 横坐标 x = range(len(movie_name)) # 票房数据 y = [73853,57767,22354,15969,14839,8725,8716,8318,7916,6764,52222]# 1.创建画布 plt.figure(figsize=(20, 8), dpi=100)# 2.绘制柱状图 plt.bar(x, y, width=0.5, color=['b','r','g','y','c','m','y','k','c','g','b'])# 2.1b修改x轴的刻度显示 plt.xticks(x, movie_name)# 2.2 添加网格显示 plt.grid(linestyle="--", alpha=0.5)# 2.3 添加标题 plt.title("电影票房收入对比")# 3.显示图像 plt.show()
-
-
4 直方图
-
定义:由一系列高度不等的纵向条纹或线段表示数据分布的情况。 一般用横轴表示数据范围,纵轴表示分布情况。
-
特点:绘制连续性的数据展示一组或者多组数据的分布状况(统计)
-
API:
plt.hist(x, bins=None)
bins : 组距
-
-
5 饼图
-
定义:用于表示不同分类的占比情况,通过弧度大小来对比各种分类。
-
特点:分类数据的占比情况(占比)
-
API:
plt.pie(x, labels=,autopct=,colors)
x:数量,自动算百分比 labels:每部分名称 autopct:占比显示指定%1.2f%% colors:每部分颜色
-
1.5 代码实现
-
一个坐标系中绘制多个图像
import matplotlib.pyplot as plt import random # from pylab import mpl## 设置显示中文字体 # mpl.rcParams["font.sans-serif"] = ["SimHei"] ## 设置正常显示符号 # mpl.rcParams["axes.unicode_minus"] = False# 0.准备数据 x = range(60) y_shanghai = [random.uniform(15, 18) for i in x] y_beijing = [random.uniform(1,3) for i in x]# 1.创建画布 plt.figure(figsize=(20, 8), dpi=100)# 2.绘制图像 plt.plot(x, y_shanghai, label="上海") plt.plot(x, y_beijing, color="r", linestyle="--", label="北京")# 2.1 添加x,y轴刻度 # 构造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])# 2.2 添加网格显示 plt.grid(True, linestyle="--", alpha=0.5)# 2.3 添加描述信息 plt.xlabel("时间") plt.ylabel("温度") plt.title("中午11点--12点某城市温度变化图", fontsize=20)# 2.4 图像保存 plt.savefig("./test.png")# 2.5 添加图例 plt.legend(loc=0)# 3.图像显示 plt.show()
-
多个坐标系显示— plt.subplots(面向对象的画图方法)
import matplotlib.pyplot as plt import random# 0.准备数据 x = range(60) y_shanghai = [random.uniform(15, 18) for i in x] y_beijing = [random.uniform(1, 5) for i in x]# 1.创建画布 # plt.figure(figsize=(20, 8), dpi=100) 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, color="r", linestyle="--", label="北京") axes[0].plot(x, y_shanghai, label="上海") axes[1].plot(x, y_beijing, color="r", linestyle="--", label="北京")# 2.1 添加x,y轴刻度 # 构造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 添加描述信息 # plt.xlabel("时间") # plt.ylabel("温度") # plt.title("中午11点--12点某城市温度变化图", fontsize=20) axes[0].set_xlabel("时间") axes[0].set_ylabel("温度") axes[0].set_title("中午11点--12点某城市温度变化图", fontsize=20) axes[1].set_xlabel("时间") axes[1].set_ylabel("温度") axes[1].set_title("中午11点--12点某城市温度变化图", fontsize=20)# # 2.4 图像保存 plt.savefig("./test.png")# # 2.5 添加图例 # plt.legend(loc=0) axes[0].legend(loc=0) axes[1].legend(loc=0)# 3.图像显示 plt.show()
2 Numpy基本使用
官方文档:https://numpy.org/doc/stable/reference/index.html
2.1 定义
源的Python科学计算库,用于快速处理任意维度的数组。
2.2 特点
-
支持常见的数组和矩阵操作
-
使用
ndarray
对象来处理多维数组 -
Numpy比Python List区别:
- Python List是一个异构(不同类型的数据)的容器
- Numpy存储的数据是同质的,类型需相同。
-
Numpy比Python List效率高:
释放GIL
:GIL限制了Python线程的并行能力,但Numpy不存在此问题。C语言实现
并行计算
:numpy内置了并行运算功能,当系统有多个核心时,做某种计算时,numpy会自动做并行计算内存结构
:
-
ndarray
-
属性:反映了数组本身固有的信息
属性名字 属性解释 ndarray.shape 数组维度的元组(行,列,维度) ndarray.ndim 数组维数 ndarray.size 数组中的元素数量 ndarray.itemsize 一个数组元素的长度(字节) ndarray.dtype 数组元素的类型 # Numpy的常量np.Inf 表示无穷大np.nan 表示非数字np.pi
-
形状
# 创建不同形状的数组 >>> 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
-
类型
# dtype是numpy.dtype类型 >>> type(score.dtype) <type 'numpy.dtype'>
名称 描述 简写 np.bool 用一个字节存储的布尔类型(True或False) ‘b’ np.int8 一个字节大小,-128 至 127 ‘i’ np.int16 整数,-32768 至 32767 ‘i2’ np.int32 整数,-2^31 至 2^32 -1 ‘i4’ np.int64 整数,-2^63 至 2^63 - 1 ‘i8’ np.uint8 无符号整数,0 至 255 ‘u’ np.uint16 无符号整数,0 至 65535 ‘u2’ np.uint32 无符号整数,0 至 2^32 - 1 ‘u4’ np.uint64 无符号整数,0 至 2^64 - 1 ‘u8’ np.float16 半精度浮点数:16位,正负号1位,指数5位,精度10位 ‘f2’ np.float32 单精度浮点数:32位,正负号1位,指数8位,精度23位 ‘f4’ np.float64 双精度浮点数:64位,正负号1位,指数11位,精度52位 ‘f8’ np.complex64 复数,分别用两个32位浮点数表示实部和虚部 ‘c8’ np.complex128 复数,分别用两个64位浮点数表示实部和虚部 ‘c16’ np.object_ python对象 ‘O’ np.string_ 字符串 ‘S’ np.unicode_ unicode类型 ‘U’ 注意:若不指定,整数默认int64,小数默认float64
-
2.3 代码实现
>>> 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')
‘|S12’ 介绍
‘|’ 表示字节顺序(不考虑顺序,< (小端))
‘S’ 表示字符串类型
‘12’ 表示数组中每个值最多包含12个字节或字符
2.3.1 生成0和1的数组
-
np.ones(shape, dtype)
创建全是1的数组 -
np.ones_like(a, dtype)
根据其它数列形状创建全是1的数组 -
np.zeros(shape, dtype)
创建全是0的数组 -
np.zeros_like(a, dtype)
根据其它数列形状创建全是0的数组# np.ones() >>>ones = np.ones([4,8]) ones# np.ones_like() >>> x = np.arange(6) >>> x = x.reshape((2, 3)) >>> x array([[0, 1, 2],[3, 4, 5]]) >>> np.ones_like(x) array([[1, 1, 1],[1, 1, 1]])
2.3.2 拷贝
-
np.array(object, dtype)
深拷贝 -
np.asarray(a, dtype)
浅拷贝a = np.array([[1,2,3],[4,5,6]]) # 从现有的数组当中创建 a1 = np.array(a) # 相当于索引的形式,并没有真正的创建一个新的 a2 = np.asarray(a)
2.3.3 生成固定范围的数组
-
np.linspace (start, stop, num, endpoint)
等差数列num
:要生成的等间隔样例数量,默认为50endpoint
:序列中是否包含stop值,默认为ture -
np.arange(start,stop, step, dtype)
等差数列step
:步长,默认值为1 -
np.logspace(start,stop, num, [base])
等比数列start
:float类型,基底base的start次幂作为左边界stop
:float类型,基底base的stop次幂作为右边界num
:要生成的等比数列数量,默认为50base
:float类型,选填,基底,默认10
2.3.4 生成随机数
正态分布是一种概率分布。正态分布是具有两个参数μ和σ的连续型随机变量的分布,第一参数μ是服从正态分布的随机变量的均值,第二个参数σ是此随机变量的标准差,所以正态分布记作N(μ,σ )
。
-
np.random模块
-
正态分布
-
np.random.randn(d0, d1, …, dn)
功能:从标准正态分布中返回一个或多个样本值
-
np.random.normal(loc=0.0, scale=1.0, size=None)
-
np.random.standard_normal(size=None)
功能:返回指定形状的标准正态分布的数组。
import numpy as np#randn(d0, d1, ..., dn) #standard_normal(size=None) #normal(loc=0.0, scale=1.0, size=None) a=np.random.randn(3,2) #三行两列的二维数组 b=np.random.standard_normal(size=[3,2]) #三行两列的二维数组 c=np.random.normal(2,3,size=[3,2]) #均值为2,标准差为3的三行两列的二维数组print(a) print('------') print(b) print('------') print(c)
-
-
均匀分布
-
np.random.rand(d0, d1, *...*, dn)
功能:返回**[0.0,1.0)**内的一组均匀分布的数。
>>>np.random.rand(2,4) array([[0.45203892, 0.52319708, 0.50009652, 0.34814468],[0.49214062, 0.77874009, 0.96667426, 0.94950402]])
-
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个值。
>>>np.random.uniform(1, 4, size = (2,3,4))array([[[3.55647219, 1.6756231 , 3.60677788, 2.3745676 ],[3.20914052, 1.63670762, 3.68718528, 1.25277517],[3.43555004, 3.76016213, 1.87874796, 2.41035426]],[[3.10438403, 3.35162098, 3.42743771, 3.25322821],[3.48925817, 2.5992673 , 2.89616745, 3.72254566],[3.00571278, 3.66503032, 3.9064071 , 2.84347013]]])
-
np.random.randint(low, high=None, size=None, dtype='l')
功能:从一个均匀分布中随机采样,生成一个整数或N维整数数组。
- 取数范围:若high不为None时,取[low,high)之间随机整数,否则取值[0,low)之间随机整数。
>>>np.random.randint(1, 4, size = (2,3,4)) array([[[1, 1, 1, 3],[1, 1, 2, 3],[1, 2, 1, 2]],[[2, 2, 3, 3],[2, 1, 2, 2],[2, 2, 3, 2]]])
-
随机整数数组
np.random.randint(low, high=None, size=None, dtype=int)
a = np.random.randint(3) b = np.random.randint(4,size=6) c = np.random.randint(2,size=(2,3)) print(a) print(b) print(c)
-
2.3.5 数组的索引、切片
- 切片赋值
hexo n "博客的文件名">>> import numpy as np
>>> arr=np.arange(10)
>>> arr_slice=arr[5:8]
>>> arr_slice[0]=-1
>>> arr_slice
array([-1, 6, 7])
>>> arr
array([ 0, 1, 2, 3, 4, -1, 6, 7, 8, 9])
- 给数组所有元素赋值
>>> arr[:]=-1
>>> arr
array([-1, -1, -1, -1, -1, -1, -1, -1, -1, -1])
- 使用copy方法复制
>>> arr_copy=arr[:].copy()
>>> arr_copy
array([-1, -1, -1, -1, -1, -1, -1, -1, -1, -1])
>>> arr_copy[:]=0
>>> arr_copy
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
>>> arr
array([-1, -1, -1, -1, -1, -1, -1, -1, -1, -1])
- 高阶数组索引
>>> import numpy as np
>>> arr2d=np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> arr2d[2]
array([7, 8, 9])
>>> arr2d[0][2]
3
>>> arr2d[0,2]
3
>>> import numpy as np
>>> arr3d=np.array([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]])
>>> arr3d
array([[[ 1, 2, 3],[ 4, 5, 6]],[[ 7, 8, 9],[10, 11, 12]]])
>>> arr3d[0]
array([[1, 2, 3],[4, 5, 6]])
>>> old_values=arr3d[0].copy()
>>> arr3d[0]=42
>>> arr3d
array([[[42, 42, 42],[42, 42, 42]],[[ 7, 8, 9],[10, 11, 12]]])
>>> arr3d[1,0]
array([7, 8, 9])
>>> x=arr3d[1]
>>> x
array([[ 7, 8, 9],[10, 11, 12]])
>>> x[0]
array([7, 8, 9])
- 高维数组切片
>>> arr2d=np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> arr2d[:2]
array([[1, 2, 3],[4, 5, 6]])
>>> arr2d[:2,1:]
array([[2, 3],[5, 6]])
>>> arr2d[1,:2]
array([4, 5])
>>> arr2d[:2,2]
array([3, 6])
>>> arr2d[:,:1]
array([[1],[4],[7]])
- 布尔型索引
>>> import numpy as np
>>> names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'])
>>> data=np.random.randn(7,4)#7行4列正太分布随机数组
>>> names
array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'], dtype='<U4')
>>> data
array([[ 0.24724057, 2.86939948, -0.82061782, -0.65745818],[-0.98602372, -0.69305692, -1.44431904, -0.85490816],[-0.73613349, 0.12700976, -1.00588979, 1.10646269],[ 1.59110894, 1.68597758, 0.39414277, 2.02308399],[-1.05607115, -0.50354292, -0.65820553, -0.77610316],[ 1.72237936, -0.07726577, 1.63462647, -0.41943148],[ 0.66744687, -1.01756773, -0.59254343, 0.19080575]])# 选出对应于名字"Bob"的所有行,对names和字符串"Bob"的比较运算将会产生一个布尔型数组。
>>> names=='Bob'
array([ True, False, False, True, False, False, False])# 获取等于'Bob'的行
>>> data[names=='Bob']
array([[ 0.24724057, 2.86939948, -0.82061782, -0.65745818],[ 1.59110894, 1.68597758, 0.39414277, 2.02308399]])# 获取不同于'Bob'的行
>>> data[names!='Bob']
array([[-0.98602372, -0.69305692, -1.44431904, -0.85490816],[-0.73613349, 0.12700976, -1.00588979, 1.10646269],[-1.05607115, -0.50354292, -0.65820553, -0.77610316],[ 1.72237936, -0.07726577, 1.63462647, -0.41943148],[ 0.66744687, -1.01756773, -0.59254343, 0.19080575]])# 对布尔索引进行列索引
>>> data[names=='Bob',2:]
array([[-0.82061782, -0.65745818],[ 0.39414277, 2.02308399]])
>>> data[names=='Bob',3]
array([-0.65745818, 2.02308399])# 反转条件符
>>> cond=names=='Will'
>>> cond
array([False, False, True, False, True, False, False])
>>> data[~cond]
array([[ 0.24724057, 2.86939948, -0.82061782, -0.65745818],[-0.98602372, -0.69305692, -1.44431904, -0.85490816],[ 1.59110894, 1.68597758, 0.39414277, 2.02308399],[ 1.72237936, -0.07726577, 1.63462647, -0.41943148],[ 0.66744687, -1.01756773, -0.59254343, 0.19080575]])# 布尔条件的运算,连接符还有|、&之类
>>> mask=(names=='Bob')|(names=='Will')
>>> mask
array([ True, False, True, True, True, False, False])
>>> data[mask]
array([[ 0.24724057, 2.86939948, -0.82061782, -0.65745818],[-0.73613349, 0.12700976, -1.00588979, 1.10646269],[ 1.59110894, 1.68597758, 0.39414277, 2.02308399],[-1.05607115, -0.50354292, -0.65820553, -0.77610316]])# 普通条件选取
>>> data[data<0]=0
>>> data
array([[0.24724057, 2.86939948, 0. , 0. ],[0. , 0. , 0. , 0. ],[0. , 0.12700976, 0. , 1.10646269],[1.59110894, 1.68597758, 0.39414277, 2.02308399],[0. , 0. , 0. , 0. ],[1.72237936, 0. , 1.63462647, 0. ],[0.66744687, 0. , 0. , 0.19080575]])# 布尔条件选取
>>> import numpy as np
>>> names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'])
>>> data=np.random.randn(7,4)#7行4列正太分布随机数组
>>> data
array([[-1.24077681, -0.48320904, 1.22145611, 0.00666619],[-0.65078721, -0.03482355, 1.74232625, 0.2979584 ],[-1.51669752, 2.04245014, 0.09453898, -0.85531867],[-1.51334497, 0.36947066, -0.87016919, 1.35107873],[-1.11285867, -2.20906849, 0.38269412, 1.85375798],[ 0.95132554, -1.54193589, 1.98741745, -0.60608077],[ 0.78902133, 1.41593836, 0.09430052, -0.25057659]])
>>> data[names!='Joe']=7
>>> data
array([[ 7. , 7. , 7. , 7. ],[-0.65078721, -0.03482355, 1.74232625, 0.2979584 ],[ 7. , 7. , 7. , 7. ],[ 7. , 7. , 7. , 7. ],[ 7. , 7. , 7. , 7. ],[ 0.95132554, -1.54193589, 1.98741745, -0.60608077],[ 0.78902133, 1.41593836, 0.09430052, -0.25057659]])
- 花式索引
# 传入单个索引数组
>>> import numpy as np
>>> arr=np.empty((8,4))#创建8行4列内容为随机值的数组
>>> arr
array([[2.65577744e-260, 7.70858946e+218, 6.01334668e-154,4.47593816e-091],[7.01413727e-009, 2.96905203e+222, 2.11672643e+214,4.56532297e-085],[4.78409596e+180, 2.44001263e-152, 2.45981714e-154,6.83528875e+212],[6.14829725e-071, 1.05161522e-153, 1.05135742e-153,2.43902457e-154],[4.83245960e+276, 6.03103052e-154, 7.06652000e-096,2.65862875e-260],[1.76380220e+241, 2.30576063e-310, 9.80013217e+040,1.55850644e-312],[1.33360318e+241, 4.09842267e-310, 2.48721655e-075,1.04922745e-312],[1.91217285e-309, 1.18182126e-125, 6.57144273e-299,5.54240979e-302]])
>>> for i in range(8):arr[i]=i>>> arr
array([[0., 0., 0., 0.],[1., 1., 1., 1.],[2., 2., 2., 2.],[3., 3., 3., 3.],[4., 4., 4., 4.],[5., 5., 5., 5.],[6., 6., 6., 6.],[7., 7., 7., 7.]])
>>> arr[[4,3,0,6]]#选特定的索引下标,选取第4,3,0,6行
array([[4., 4., 4., 4.],[3., 3., 3., 3.],[0., 0., 0., 0.],[6., 6., 6., 6.]])
>>> arr[[-3,-5,-7]]#选择特定的索引下标,选取第-3,-5,-7行
array([[5., 5., 5., 5.],[3., 3., 3., 3.],[1., 1., 1., 1.]])# 传入多个索引数组
>>> arr=np.arange(32).reshape((8,4))
>>> arr
array([[ 0, 1, 2, 3],[ 4, 5, 6, 7],[ 8, 9, 10, 11],[12, 13, 14, 15],[16, 17, 18, 19],[20, 21, 22, 23],[24, 25, 26, 27],[28, 29, 30, 31]])
>>> arr[[1,5,7,2],[0,3,1,2]]#选取(1,0),(5,3),(7,1),(2,2)对应元素
array([ 4, 23, 29, 10])>>> arr[[1,5,7,2]][:,[0,3,1,2]]#先选取第1,5,7,2行,再将每行按照0,3,1,2这个顺序交换
array([[ 4, 7, 5, 6],[20, 23, 21, 22],[28, 31, 29, 30],[ 8, 11, 9, 10]])
2.3.6 形状修改
-
ndarray.reshape(shape, order)
返回一个具有相同数据域,但shape不一样的视图
行、列不进行互换
# 在转换形状的时候,一定要注意数组的元素匹配 stock_change.reshape([5, 4]) stock_change.reshape([-1,10]) # 数组的形状被修改为: (2, 10), -1: 表示通过待计算
-
ndarray.resize(new_shape)
修改数组本身的形状(需要保持元素个数前后相同)
行、列不进行互换
stock_change.resize([5, 4]) # 查看修改后结果 stock_change.shape (5, 4)
-
ndarray.T
数组的转置
将数组的行、列进行互换
stock_change.T.shape (4, 5)
2.3.7 类型修改
-
ndarray.astype(type)
返回修改了类型之后的数组
stock_change.astype(np.int32)
-
ndarray.tobytes([order])
构造包含数组中原始数据字节的Python字节
arr = np.array([[[1, 2, 3], [4, 5, 6]], [[12, 3, 34], [5, 6, 7]]]) arr.tobytes()
常见问题:jupyter输出太大可能导致崩溃问题
IOPub data rate exceeded.The notebook server will temporarily stop sending outputto the client in order to avoid crashing it.To change this limit, set the config variable`--NotebookApp.iopub_data_rate_limit`.
解决方案
(1)创建配置文件
jupyter notebook --generate-config vi ~/.jupyter/jupyter_notebook_config.py
(2)取消注释,修改限制
## (bytes/sec) Maximum rate at which messages can be sent on iopub before they # are limited. c.NotebookApp.iopub_data_rate_limit = 10000000
2.3.8 数组去重
-
np.unique()
temp = np.array([[1, 2, 3, 4],[3, 4, 5, 6]]) >>> np.unique(temp) array([1, 2, 3, 4, 5, 6])
2.3.9 逻辑运算
- 利用布尔索引进行运算,提取满足布尔条件的值或者给满足条件的值进行赋值等。
2.3.10 通用判断函数
-
np.all()
# 判断前两名同学的成绩[0:2, :]是否全及格 >>> np.all(score[0:2, :] > 60) False
-
np.any()
# 判断前两名同学的成绩[0:2, :]是否有大于90分的 >>> np.any(score[0:2, :] > 80) True
2.3.11 三元运算符
-
np.where()
# 判断前四名学生,前四门课程中,成绩中大于60的置为1,否则为0 temp = score[:4, :4]np.where(temp > 60, 1, 0) # 判断前四名学生,前四门课程中,成绩中大于60且小于90的换为1,否则为0 np.where(np.logical_and(temp > 60, temp < 90), 1, 0)# 判断前四名学生,前四门课程中,成绩中大于90或小于60的换为1,否则为0 np.where(np.logical_or(temp > 90, temp < 60), 1, 0)
2.3.12 统计运算
- min(a, axis) # 最小值
- max(a, axis]) # 最大值
- median(a, axis) # 中位数
- mean(a, axis, dtype) # 均值
- std(a, axis, dtype) # 标准差
- var(a, axis, dtype) # 方差
- argmin(a, axis) # 对应最小值数据的下标
- argmin(a, axis) # 对应最大值数据的下标
2.3.13 数组间的运算
广播机制
:数组在进行矢量化运算时,要求数组的形状是相等的。当形状不相等的数组执行算术运算的时候,就会出现广播机制,该机制会对数组进行扩展,使数组的shape属性值一样,以进行矢量化运算。
2.3.14 矩阵运算
-
matrix和array区别
- 矩阵必须是
2维
的 - array可以是
多维
的
- 矩阵必须是
-
矩阵运算规则
-
创建矩阵
-
np.matrix(np.random.randint(0, 10, (2, 5)))
-
np.identity(n)
# 创建n维单位矩阵
-
-
矩阵操作
array1 * array2
# 矩阵乘法array ** -1
# 矩阵转置
-
矩阵API
- np.matmul(a,b) #矩阵乘法,禁止矩阵与标量进行计算
- np.dot(a,b) # 矩阵乘法,可以进行矩阵与标量的计算
3 Pandas基本使用
官方文档:https://pandas.pydata.org/docs/reference/index.html
3.1 定义
python+data+analysis
的组合缩写(另一种解释为:pandas = panel + dataframe + series
),是python中基于numpy和matplotlib的第三方数据分析库,与后两者共同构成了python数据分析的基础工具包,享有数分三剑客之名。有数据分析界的瑞士军刀之称。
3.2 特点
-
增强图表可读性
- 常用的数据分析与统计功能,包括基本统计量、分组统计分析等
-
便捷的数据处理能力
- 类比SQL的join和groupby功能,pandas可以很容易实现SQL这两个核心功能,实际上,SQL的绝大部分DQL和DML操作在pandas中都可以实现
- 类比Excel的数据透视表功能,Excel中最为强大的数据分析工具之一是数据透视表,这在pandas中也可轻松实现
- 自带正则表达式的字符串向量化操作,对pandas中的一列字符串进行通函数操作,而且自带正则表达式的大部分接口
- 丰富的时间序列向量化处理接口
-
读取文件方便
-
按索引匹配的广播机制,这里的广播机制与numpy广播机制还有很大不同
-
便捷的数据读写操作,相比于numpy仅支持数字索引,pandas的两种数据结构均支持标签索引,包括bool索引也是支持的
-
-
封装了Matplotlib、Numpy的画图和计算
- 集成matplotlib的常用可视化接口,无论是series还是dataframe,均支持面向对象的绘图接口
3.3 操作
-
Series
:一维数组结构,主要由一组数据和与之相关的索引两部分构成。# 导入pandas import pandas as pd# API结构 pd.Series(data=None, index=None, dtype=None)pd.Series(np.arange(10))pd.Series([6.7,5.6,3,10,2], index=[1,2,3,4,5])color_count = pd.Series({ 'red':100, 'blue':200, 'green': 500, 'yellow':1000})
- pd.Series.data # 获得数据
-
pd.Series.index # 获得索引
- pd.Series.value # 获得值
- pd.Series.dtype # 获得类型
-
DataFrame
:二维数组,既有行索引,又有列索引。# 导入pandas import pandas as pd# 行索引,表明不同行,横向索引,叫index,0轴,axis=0 # 列索引,表名不同列,纵向索引,叫columns,1轴,axis=1 pd.DataFrame(data=None, index=None, columns=None)pd.DataFrame(np.random.randn(2,3))pd.DataFrame(np.random.randint(0, 10, (10, 10)))# 构造行索引序列 subjects = ["语文", "数学", "英语", "政治", "体育"] # 构造列索引序列 stu = ['同学' + str(i) for i in range(score_df.shape[0])] # 添加行列索引 data = pd.DataFrame(score, columns=subjects, index=stu)
- pd.DataFrame.shape # 数组结构
- pd.DataFrame.index # 数组行索引列表
- pd.DataFrame.colums # 数组列索引列表
- pd.DataFrame.values # 数组的值
- pd.DataFrame.T # 数组转置
- pd.DataFrame.head(n) # 数组前n行,默认5行
- pd.DataFrame.tail(n) # 数组后n行,默认5行
- pd.reset_index(drop=False) # 设置新的下标索引,drop为是否删除原来索引,默认False。
- set_index(keys, drop=True) # 以名为keys的列表值设置为新索引,drop默认值为True。
-
MultiIndex:三维的数据结构
-
多级索引(层次化索引),可以在Series、DataFrame对象上拥有2个以及2个以上的索引
df = pd.DataFrame({ 'month': [1, 4, 7, 10],'year': [2012, 2014, 2013, 2014],'sale':[55, 40, 84, 31]}) # 使用DataFrame构造多索引的MultiIndex结构 df = df.set_index(['year', 'month']) df>>>sale year month 2012 1 55 2014 4 40 2013 7 84 2014 10 31# 打印行索引结果 df.index>>> MultiIndex(levels=[[2012, 2013, 2014], [1, 4, 7, 10]],labels=[[0, 2, 1, 2], [0, 1, 2, 3]],names=['year', 'month'])
-
代码实现
arrays = [[1, 1, 2, 2], ['red', 'blue', 'red', 'blue']] pd.MultiIndex.from_arrays(arrays, names=('number', 'color'))# 结果 MultiIndex(levels=[[1, 2], ['blue', 'red']],codes=[[0, 0, 1, 1], [1, 0, 1, 0]],names=['number', 'color'])
-
3.4 Numpy和Pandas区别及联系
-
Pandas是在Numpy基础上实现,其核心数据结构与Numpy的ndarray十分相似,但Pandas与Numpy的关系不是替代,而是互为补充。二者之间主要区别是:
-
从数据结构上看:
-
numpy的核心数据结构是
ndarray
,支持任意维数的数组,但要求单个数组内所有数据是同质的
,即类型必须相同; -
pandas的核心数据结构是
series
和dataframe
,仅支持一维和二维数据,但数据内部可以是异构
数据,仅要求同列数据类型一致即可 -
numpy的数据结构仅支持
数字索引
-
pandas数据结构则同时支持
数字索引
和标签索引
-
-
从功能定位上看:
-
numpy虽然也支持字符串等其他数据类型,但仍然主要是用于
数值计算
,尤其是内部集成了大量矩阵计算模块,例如基本的矩阵运算、线性代数、fft、生成随机数等,支持灵活的广播机制 -
pandas主要用于
数据处理与分析
,支持包括数据读写、数值计算、数据处理、数据分析和数据可视化全套流程操作
Excel透视表:数据透视表(Pivot Table)是一种交互式的表,可以进行某些计算,如求和与计数等。所进行的计算与数据跟数据透视表中的排列有关。
之所以称为数据透视表,是因为可以动态地改变它们的版面布置,以便按照不同方式分析数据,也可以重新安排行号、列标和页字段。每一次改变版面布置时,数据透视表会立即按照新的布置重新计算数据。另外,如果原始数据发生更改,则可以更新数据透视表。
-
-
3.5 Series和Dataframe区别
Pandas核心数据结构有两种,即一维的series和二维的dataframe,二者可以分别看做是在numpy一维数组和二维数组的基础上增加了相应的标签信息。正因如此,可以从两个角度理解series和dataframe:
- series和dataframe分别是一维和二维数组,因为是数组,所以numpy中关于数组的用法基本可以直接应用到这两个数据结构,包括数据创建、切片访问、通函数、广播机制等
- series是带标签的一维数组,所以还可以看做是
类字典
结构:标签是key,取值是value;而dataframe则可以看做是嵌套字典
结构,其中列名是key,每一列的series是value。所以从这个角度讲,pandas数据创建的一种灵活方式就是通过字典或者嵌套字典,同时也自然衍生出了适用于series和dataframe的类似字典访问的接口,即通过loc索引访问。
3.6 基本数据操作
-
1 索引
-
直接索引 – 先列后行,是需要通过索引的字符串进行获取
-
loc
– 先行后列,是需要通过索引的字符串进行获取 -
iloc
– 先行后列,是通过下标进行索引 -
ix
– 先行后列, 可以用上面两种方法混合进行索引# 使用loc:只能指定行列索引的名字 data.loc['2018-02-27':'2018-02-22', 'open']>>> 2018-02-27 23.53 2018-02-26 22.80 2018-02-23 22.88 Name: open, dtype: float64# 使用iloc可以通过索引的下标去获取 # 获取前3天数据,前5列的结果 data.iloc[:3, :5]>>>open high close low 2018-02-27 23.53 25.88 24.16 23.53 2018-02-26 22.80 23.78 23.53 22.80 2018-02-23 22.88 23.37 22.82 22.71# 使用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
-
-
2 赋值
- data[“***”] = **
- data.*** =
-
3 排序
-
Dataframe
-
对象.sort_values(by=, ascending=)
# ascending默认为True,表示升序排列 -
对象.sort_index()
# 对索引进行排序# 按照开盘价大小进行排序 , 使用ascending指定按照大小排序 data.sort_values(by="open", ascending=True).head()# 按照多个键进行排序 data.sort_values(by=['open', 'high'])# 对索引进行排序 data.sort_index()
-
-
series
-
对象.sort_values(ascending=True)
-
对象.sort_index()
data['p_change'].sort_values(ascending=True).head()>>> 2015-09-01 -10.03 2015-09-14 -10.02 2016-01-11 -10.02 2015-07-15 -10.02 2015-08-26 -10.01 Name: p_change, dtype: float64# 对索引进行排序 data['p_change'].sort_index().head()>>> 2015-03-02 2.62 2015-03-03 1.44 2015-03-04 1.57 2015-03-05 2.02 2015-03-06 8.51 Name: p_change, dtype: float64
-
-
3.7 DataFram运算
-
1 算术运算
对象.add()
# 求和对象.sub()
# 求差
-
2 逻辑运算
-
1.逻辑运算符号
# 多个逻辑判断 data[(data["open"] > 23) & (data["open"] < 24)].head()
-
2.逻辑运算函数
-
对象.query(expr)
# 查询字符串exprdata.query("open<24 & open>23").head()
-
对象.isin(values)
# 判断对象是否在values中# 可以指定值进行一个判断,从而进行筛选操作 data[data["open"].isin([23.53, 23.85])]
-
-
-
3 统计运算
-
1.对象.describe() # 综合分析,得出多种统计结果,
count
,mean
,std
,min
,max
等# 计算平均值、标准差、最大值、最小值 data.describe()
-
2.统计函数
函数 作用 count 计数 sum 求和 mean 均值 median 中位数 min 最小值 max 最大值 mode 众数 abs 绝对值 prod 所有项乘积 std 标准差 var 方差 idxmax 最大值位置 idxmin 最小值位置 # 求出最小值的位置 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
-
3.累积统计函数
函数 作用 cumsum 计算前1/2/3/…/n个数的和 cummax 计算前1/2/3/…/n个数的最大值 cummin 计算前1/2/3/…/n个数的最小值 cumprod 计算前1/2/3/…/n个数的积 # 排序之后,进行累计求和 data = data.sort_index()stock_rise = data['p_change'] # plot方法集成了前面直方图、条形图、饼图、折线图 stock_rise.cumsum()2015-03-02 2.62 2015-03-03 4.06 2015-03-04 5.63 2015-03-05 7.65 2015-03-06 16.16 2015-03-09 16.37 2015-03-10 18.75 2015-03-11 16.36 2015-03-12 15.03 2015-03-13 17.58 2015-03-16 20.34 2015-03-17 22.42
-
-
4 自定义运算
-
apply(func, axis=0)
data[['open', 'close']].apply(lambda x: x.max() - x.min(), axis=0)>>> open 22.74 close 22.85 dtype: float64
-
3.8 Pandas 画图
-
DataFrame.plot(kind='line')
-
kind : str,需要绘制图形的种类
line
:折线图bar
: 柱状图barh
: 水平直方图hist
: 直方图pie
: 饼状图scatter
: 散点图
详见官方文档:https://pandas.pydata.org/pandas-docs/stable/reference/frame.html
-
-
pandas.Series.plot()
? 详见官方文档:https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.plot.html?highlight=plot#pandas.DataFrame.plot
3.9 文件读取与存储
-
CSV
-
pandas.read_csv(filepath_or_buffer, sep =',', usecols )
# 读取文件,并且指定只获取'open', 'close'指标 # sep :分隔符,默认用","隔开 # usecols:指定读取的列名,列表形式 data = pd.read_csv("./data/stock_day.csv", usecols=['open', 'close'])open close 2018-02-27 23.53 24.16 2018-02-26 22.80 23.53 2018-02-23 22.88 22.82 2018-02-22 22.25 22.28 2018-02-14 21.49 21.92
-
DataFrame.to_csv(path_or_buf=None, sep=', ’, columns=None, header=True, index=True, mode='w', encoding=None)
# index:存储不会讲索引值变成一列数据 data[:10].to_csv("./data/test.csv", columns=['open'], index=False)
-
-
HDF5
-
pandas.read_hdf(path_or_buf,key =None,** kwargs)
# 读取day_close的数据 new_close = pd.read_hdf("./data/test.h5", key="day_close")
-
DataFrame.to_hdf(path_or_buf, *key*, **\*kwargs*)
# 将day_close数据项存储到一个文件 day_close.to_hdf("./data/test.h5", key="day_close")
-
-
JSON
-
pandas.read_json(path_or_buf=None, orient=None, typ='frame', lines=False)
# orient指定存储的json格式,lines指定按照行去变成一个样本 json_read = pd.read_json("./data/Sarcasm_Headlines_Dataset.json", orient="records", lines=True)
-
DataFrame.to_json(*path_or_buf=None*, *orient=None*, *lines=False*)
# 将Pandas 对象存储为json格式 # path_or_buf=None:文件地址 # orient:存储的json形式,{‘split’,’records’,’index’,’columns’,’values’} # lines:一个对象存储为一行
-
3.10 缺失值处理
- isnull、notnull判断是否存在缺失值
np.any(pd.isnull(movie))
# 里面如果有一个缺失值,就返回Truenp.all(pd.notnull(movie))
# 里面如果有一个缺失值,就返回False
- dropna删除np.nan标记的缺失值
movie.dropna()
- fillna填充缺失值
movie[i].fillna(value=movie[i].mean(), inplace=True)
- replace替换具体某些值
wis.replace(to_replace="?", value=np.NaN)
3.11 数据离散化
-
数据离散化目的:
- 可以用来减少给定连续属性值的个数
- 在连续属性的值域上,将值域划分为若干个离散的区间,最后用不同的符号或整数值代表落在每个子区间中的属性值。
-
实现API
-
pd.qcut(data, q)
对数据进行分组将数据分组,一般会与value_counts搭配使用,统计每组的个数
-
series.value_counts()
# 统计分组次数 -
pd.cut(data, bins)
# 自定义区间分组
-
-
独热编码(one-hot编码)
-
把每个类别生成一个布尔列,这些列中只有一列可以为这个样本取值为
-
pandas.get_dummies(*data*, *prefix=None*)
# 得出one-hot编码矩阵 dummies = pd.get_dummies(p_counts, prefix="rise")
-
3.12 高级处理-合并
-
pd.concat([数据1, 数据2], axis=1) # 数据合并
# 按照行索引进行 pd.concat([data, dummies], axis=1)
-
pd.merge(left, right, how=‘inner’, on=None)
- left: DataFrame
- right: 另一个DataFrame
- how – 以何种方式连接
- on – 连接的键的依据是哪几个
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'])
3.13 高级处理-交叉表与透视表
-
交叉表:
交叉表用于计算一列数据对于另外一列数据的分组个数(用于统计分组频率的特殊透视表)
- pd.crosstab(value1, value2)
-
透视表:
透视表是将原有的DataFrame的列分别作为行索引和列索引,然后对指定的列应用聚集函数
-
data.pivot_table()
-
DataFrame.pivot_table([], index=[])
# 寻找星期几跟股票张得的关系 # 1、先把对应的日期找到星期几 date = pd.to_datetime(data.index).weekday data['week'] = date# 2、假如把p_change按照大小去分个类0为界限 data['posi_neg'] = np.where(data['p_change'] > 0, 1, 0)# 通过交叉表找寻两列数据的关系 count = pd.crosstab(data['week'], data['posi_neg'])# 算数运算,先求和 sum = count.sum(axis=1).astype(np.float32)# 进行相除操作,得出比例 pro = count.div(sum, axis=0)pro.plot(kind='bar', stacked=True) plt.show()# 通过透视表,将整个过程变成更简单一些 data.pivot_table(['posi_neg'], index='week')
-
3.14 高级处理-分组与聚合
-
DataFrame.groupby(key, as_index=False)
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()>>> color green 2.025 red 2.380 white 5.560 Name: price1, dtype: float64# 分组,数据的结构不变 col.groupby(['color'], as_index=False)['price1'].mean()>>> color price1 0 green 2.025 1 red 2.380 2 white 5.560