导图社区 数据分析
比较详细的python数据分析导图,包括安装,pandas,numpy等,有需要的小伙伴们赶紧收藏吧!
编辑于2023-10-24 00:06:19这是一篇关于C 学习路线图的思维导图,主要内容包括:基础语法,面向对象编程,标准模板库(STL),高级特性,Qt 学习路线图,MFC 学习路线图,API 学习路线图,实践和项目,学习资源和工具,调试和性能优化,软件工程实践。
用qt框架写的驾校科目一考试系统,包含考试时间、验证账号密码、验证邮箱地址 登录界面、创建项目、布局按钮、初始化题库、提交试题等。
Windows API函数大全,无论你是初学者还是经验丰富的开发者,Windows API函数大全都能帮助你更好地理解Windows操作系统的底层机制,掌握高效开发Windows应用程序的技巧和方法。
社区模板帮助中心,点此进入>>
这是一篇关于C 学习路线图的思维导图,主要内容包括:基础语法,面向对象编程,标准模板库(STL),高级特性,Qt 学习路线图,MFC 学习路线图,API 学习路线图,实践和项目,学习资源和工具,调试和性能优化,软件工程实践。
用qt框架写的驾校科目一考试系统,包含考试时间、验证账号密码、验证邮箱地址 登录界面、创建项目、布局按钮、初始化题库、提交试题等。
Windows API函数大全,无论你是初学者还是经验丰富的开发者,Windows API函数大全都能帮助你更好地理解Windows操作系统的底层机制,掌握高效开发Windows应用程序的技巧和方法。
数据分析
1| 基础
Jupyter Notebook 的使用
1. jupyter 安装与适配
1. 首先在终端下安装 jupyter
pip install jupyter
pip install jupyter --upgrade
2. 安装jupyter拓展库
pip install autopep8 # 安装pep8代码规范的模块
pip install jupyter_nbextensions_configurator # 拓展工具配置项
pip install jupyter_contrib_nbextensions # 安装 jupyter 拓展包
pip install yapf # 安装拓展包依赖的第三方功能模块
3. 拓展包安装后需要执行命令适配
"""拓展包适配"""
jupyter contrib nbextension install --user
jupyter nbextensions_configurator enable --user
jupyter nbextension enable code_prettify/code_prettify
4. 环境搭建好后,在命令行下输入 `jupyter notebook` 命令,会自动弹出浏览器窗口打开 Jupyter Notebook
# 输入命令
jupyter notebook
5. 可能出现错误
错误图片
参考文章解决
6. 打开`jupyter notebook`以后, 在`Nbextensions`选项下勾选配置选项
7. 配置环境变量
变量名:LANG
变量值:zh_CN.UTF8
2. 创建文件
2. 创建文件 new-->python3 标题栏: 点击标题(如Untitled)修改文档名
1. 选中需要创建的路径--> 删除输入cmd--> 在终端中输入jupyter notebook
2. 在文件夹里空白处按(ctrl+shift+鼠标右键) -->点击(在此处打开Powershell窗口), 操作与cmd终端一样
两种方法
3. cell 单元格操作
1. 什么是cell?- **cell**:一对In Out会话被视作一个代码单元,称为cell- cell行号前的 * ,表示代码正在运行
2. 两种模式
2. 编辑模式(Enter) 命令模式下回车Enter或鼠标双击cell进入编辑模式 可以操作cell内文本或代码,剪切/复制/粘贴移动等操作 命令模式(Esc) 按Esc退出编辑,进入命令模式 可以操作cell单元本身进行剪切/复制/粘贴/移动等操作
3. 快捷键操作
两种模式通用快捷键
Shift+Enter,执行本单元代码,并跳转到下一单元 Ctrl+Enter,执行本单元代码,留在本单元
命令模式 按ESC进入
Y :在命令模式下转入代码状态 M :在命令模式下切换到 Markdown R :普通文本,运行不会输出结果 L :为当前cell加上行号 A:在该单元格的上方插入新单元格 B:在该单元格的下方插入新单元格 X:剪切选中的单元 C:复制选中的单元 V:粘贴到下方单元 DD:删除选中的单元(敲两个D)
其他(了解)
双击D:删除当前cell Z,回退 快速跳转到首个cell,Crtl+Home 快速跳转到最后一个cell,Crtl+End -->
编辑模式 按Enter进入
补全代码:变量、方法后跟Tab键 为一行或多行代码添加/取消注释:Ctrl+/(Mac:CMD+/)
其他(了解)
多光标操作:Ctrl键点击鼠标(Mac:CMD+点击鼠标) 回退:Ctrl+Z(Mac:CMD+Z) 重做:Ctrl+Y(Mac:CMD+Y)
4. 鼠标操作
5. markdown演示 掌握标题和缩进即可
6. 其他操作 函数名 + ? 查看源码
7. Tab 自动补全: 如果敲代码没有自动补全, 可以用**Tab**查看代码提示
4. 附录 Jupyter 常用快捷键
1. 命令模式 (按Esc键)
1. Enter:转入编辑模式 Shift-Enter:运行本单元,选中下个单元 Ctrl-Enter:运行本单元 Alt-Enter:运行本单元,在其下插入新单元 Y:单元转入代码状态 M:单元转入markdown状态 R:单元转入raw状态 1:设定 1 级标题 2:设定 2 级标题 3:设定 3 级标题 4:设定 4 级标题 5:设定 5 级标题 6:设定 6 级标题 Up:选中上方单元 K:选中上方单元 Down:选中下方单元 J:选中下方单元 Shift-K:扩大选中上方单元 Shift-J:扩大选中下方单元 A:在上方插入新单元 B:在下方插入新单元 X:剪切选中的单元 C:复制选中的单元 Shift-V:粘贴到上方单元 V:粘贴到下方单元 Z:恢复删除的最后一个单元 D,D:删除选中的单元 Shift-M:合并选中的单元 Ctrl-S:文件存盘 S:文件存盘 L:转换行号 O:转换输出 Shift-O:转换输出滚动 Esc:关闭页面 Q:关闭页面 H:显示快捷键帮助 I,I:中断Notebook内核 0,0:重启Notebook内核 Shift:忽略 Shift-Space:向上滚动 Space:向下滚动
2. 编辑模式 (按回车键)
2. Tab : 代码补全或缩进 Shift-Tab : 提示 Ctrl-] : 缩进 Ctrl-[ : 解除缩进 Ctrl-A : 全选 Ctrl-Z : 复原 Ctrl-Shift-Z : 再做 Ctrl-Y : 再做 Ctrl-Home : 跳到单元开头 Ctrl-Up : 跳到单元开头 Ctrl-End : 跳到单元末尾 Ctrl-Down : 跳到单元末尾 Ctrl-Left : 跳到左边一个字首 Ctrl-Right : 跳到右边一个字首 Ctrl-Backspace : 删除前面一个字 Ctrl-Delete : 删除后面一个字 Esc : 进入命令模式 Ctrl-M : 进入命令模式 Shift-Enter : 运行本单元,选中下一单元 Ctrl-Enter : 运行本单元 Alt-Enter : 运行本单元,在下面插入一单元 Ctrl-Shift-- : 分割单元 Ctrl-Shift-Subtract : 分割单元 Ctrl-S : 文件存盘 Shift : 忽略 Up : 光标上移或转入上一单元 Down :光标下移或转入下一单元
2| matplotlib 绘图
Matplotlib
安装模块 pip install matplotlib
基础使用
导入模块 import matplotlib.pyplot as plt
操作步骤
1.创建画布 -- plt.figure() plt.figure(figsize=(), dpi=) figsize:指定图的长宽 dpi:图像的清晰度(分辨率) 返回fig对象 2.绘制图像 -- plt.plot(x, y) 3.显示图像 -- plt.show()
折线图
绘制与显示步骤
准备数据 可以是列表,也可以是列表推导式 创建画布 plt.figure(figsize=(), dpi=) # (宽高,分辨率) 绘制图像 plt.plot(x, y) 显示图像 -- plt.show()
添加辅助功能
导入random模块 import random 注意:需要重新执行才有效果 random.uniform(15, 18) 刻度在15-18
准备数据
添加x,y刻度
添加网格显示
添加网格显示 plt.grid(True, linestyle="--", alpha=1) 参数1 --> 是否显示网格 参数2 --> 虚线/实线 参数3 --> 显示的透明度
添加描述信息
添加描述信息 plt.xlabel("时间") # 横坐标 plt.ylabel("温度") # 纵坐标 # 添加标题 \n 可让标题换行 plt.title("中午11点-12点某城市温度变化图", fontsize=20)
绘制多个图像
1 多次plot
2 设置图形风格
3 显示图例 plt.legend(loc="best")
4 多个坐标系显示
plt.subplots(面向对象的画图方法)
matplotlib.pyplot.subplots(nrows=1, ncols=1, **fig_kw) 创建一个带有多个axes(坐标系/绘图区)的图
nrows=1 行 ncols=1 列 设置标题等方法不同: set_xticks set_yticks set_xlabel set_ylabel
关于axes子坐标系的更多方法:参考
注意:
plt.函数名() 相当于面向过程的画图方法, axes.set_方法名() 相当于面向对象的画图方法。
小结
添加x,y轴刻度【知道】 plt.xticks() plt.yticks() 注意:在传递进去的第一个参数必须是数字,不能是字符串,如果是字符串吗,需要进行替换操作 添加网格显示【知道】 plt.grid(linestyle="--", alpha=0.5) 添加描述信息【知道】 plt.xlabel() plt.ylabel() plt.title() 图像保存【知道】 plt.savefig("路径") 多次plot【了解】 直接进行添加就OK 显示图例【知道】 plt.legend(loc="best") 注意:一定要在plt.plot()里面设置一个label,如果不设置,没法显示 多个坐标系显示【了解】 plt.subplots(nrows=, ncols=) 折线图的应用【知道】 1.应用于观察数据的变化 2.可是画出一些数学函数图像
常见图形绘制
1. 折线图
1. 以折线的上升或下降来表示统计数量的增减变化的统计图 特点:能够显示数据的变化趋势,反映事物的变化情况。(变化) api:plt.plot(x, y)
2. 柱状图(条形图)
2. 排列在工作表的列或行中的数据可以绘制到柱状图中。 特点:绘制连离散的数据,能够一眼看出各个数据的大小,比较数据之间的差别。(统计/对比) api:plt.bar(x, width, align='center', kwargs) 应用场景:数量统计,频率统计。 条形图的绘制方式跟折线图非常的类似,只不过是换成了plt.bar方法
`plt.bar`方法
`plt.bar`方法有以下常用参数
x:一个数组或者列表,代表需要绘制的条形图的x轴的坐标点。 height:一个数组或者列表,代表需要绘制的条形图y轴的坐标点。 width:每一个条形图的宽度,默认是0.8的宽度。 bottom:y轴的基线,默认是0,也就是距离底部为0. align:对齐方式,默认是center,也就是跟指定的x坐标居中对齐,还有为edge,靠边对齐,具体靠右边还是靠左边,看width的正负。 color:条形图的颜色。 返回值为BarContainer,是一个存储了条形图的容器,而条形图实际上的类型是matplotlib.patches.Rectangle对象。
更多参考
1 条形图的绘制
2 横向条形图
3 分组条形图
4 堆叠条形图
案例网址
3. 散点图
3. 用两组数据构成多个坐标点,考察坐标点的分布,判断两变量之间是否存在某种关联或总结坐标点的分布模式。 特点:判断变量之间是否存在数量关联趋势,展示离群点(分布规律)** api:plt.scatter(x, y)
4. 饼图
4. 用于表示不同分类的占比情况,通过弧度大小来对比各种分类。饼图可以看成数据的合计后的占比,适合突出表现份额。 特点:分类数据的占比情况(占比) api:plt.pie(x, labels=,autopct=,colors)
a. 参数
1. `x`:饼图的比例序列。
2. `labels`:饼图上每个分块的名称文字。
3. `explode`:设置某几个分块是否要分离饼图。
7. 其他参数:
4. `autopct`:设置比例文字的展示方式。 比如保留几个小数等。
5. `shadow`:是否显示阴影。
6. `textprops`:文本的属性(颜色,大小等)。
b. 返回值
1. `patches`:饼图上每个分块的对象。
2. `texts`:分块的名字文本对象。
3. `autotexts`:分块的比例文字对象。
5. 雷达图
1. plt.polar 绘制雷达图
2. 注意事项
1. 因为`polar`并不会完成线条的闭合绘制, 所以我们在绘制的时候需要在`theta`中和`values`中在最后多重复添加第0个位置的值, 然后在绘制的时候就可以和第1个点进行闭合了。
2. `polar`只是绘制线条, 所以如果想要把里面进行颜色填充, 那么需要调用`fill`函数来实现。
3. `polar`默认的圆圈的坐标是角度, 如果我们想要改成文字显示, 那么可以通过`xticks`来设置。
6. 小结
(1) - 折线图【知道】
(2) - 能够显示数据的变化趋势,反映事物的变化情况。(变化)
(3) - plt.plot()
(4) - 散点图【知道】
(5) - 判断变量之间是否存在数量关联趋势,展示离群点(分布规律)
(6) - plt.scatter()
(7) - 柱状图【知道】
(8) - 绘制连离散的数据,能够一眼看出各个数据的大小,比较数据之间的差别。(统计/对比)
(9) - plt.bar(x, width, align="center")
(10) - 直方图【知道】
(11) - 绘制连续性的数据展示一组或者多组数据的分布状况(统计)
(12) - plt.hist(x, bins)
(13) - 饼图【知道】
(14) - 用于表示不同分类的占比情况,通过弧度大小来对比各种分类
(15) - plt.pie(x, labels, autopct, colors)
3| Numpy库
1. 安装
安装
通过 `pip install numpy` 即可安装, 如果是 anaconda 环境,默认就安装好了
教程地址
官网
中文文档
2. ndarray
1| ndarray 的属性
数组属性反映了数组本身固有的信息。
| 属性名字 | 属性解释 |
| :---------------: | :------------------------: |
| **ndarray.shape** | 数组维度的元组 |
| ndarray.ndim | 数组维数 |
| ndarray.size | 数组中的元素数量 |
| ndarray.itemsize | 一个数组元素的长度(字节) |
| **ndarray.dtype** | 数组元素的类型 |
2| ndarray 的形状 score.shape
3| ndarray的类型 type(score.dtype)
3| dtype是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' |
3. 基本操作
1. 生成数组的方法
np.ones(shape, dtype)
np.zeros(shape, dtype)
2. 从现有数组生成
生成方式
np.array(object, dtype)**
np.asarray(a, dtype
3. 生成固定范围的数组
a. 等差数组 — 指定数量
np.linspace (start, stop, num, endpoint)
参数:
- start:序列的起始值
- stop:序列的终止值
- num:要生成的等间隔样例数量,默认为50
- endpoint:序列中是否包含stop值,默认为ture
b. 等差数组 — 指定步长
np.arange(start,stop, step, dtype) step:步长,默认值为1
c. 等比数列
num:要生成的等比数列数量,默认为50
4. 随机数组模块 np.random 模块
a. 正态分布
创建
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) 返回指定形状的标准正态分布的数组。
b. 均匀分布
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), 则输出m*n*k个样本,缺省时输出1个值。
返回值:ndarray类型,其形状和参数size中描述一致。
np.random.randint(*low*, *high=None*, *size=None*, *dtype='l'*)
取数范围:若high不为None时,取[low,high)之间随机整数,否则取值[0,low)之间随机整数。
从一个均匀分布中随机采样,生成一个整数或N维整数数组
5. 数组的操作
A. 修改数组维度 ndarray.reshape(shape, order) 形状(shape行,order列)
B. reshape 和 resize 方法
reshape 是将数组转换成指定的形状, 然后返回转换后的结果, 对于原数组的形状是不会发生改变的
resize 是将数组转换成指定的形状, 会直接修改数组本身。并不会返回任何值
C. flatten 和 ravel 方法
两个方法都是将多维数组转换为一维数组,但是有以下不同:
1. flatten 是将数组转换为一维数组后, 然后将这个拷贝返回回去, 所以后续对这个返回值进行修改不会影响之前的数组。
2. ravel 是将数组转换为一维数组后, 将这个视图(可以理解为引用)返回回去, 所以后续对这个返回值进行修改会影响之前的数组。
D. ndarray.T
数组的转置
将数组的行、列进行互换
E. 数组操作
1| 索引、切片
- 直接进行索引,切片
- 对象[:, :] -- 先行后列
2| 数组的切割(了解) 通过`hsplit`和`vsplit`以及`array_split`可以将一个数组进行切割
hsplit:按照水平方向进行切割。用于指定分割成几列,可以使用数字来代表分成几部分,也可以使用数组来代表分割的地方。
vsplit:按照垂直方向进行切割。用于指定分割成几行,可以使用数字来代表分成几部分,也可以使用数组来代表分割的地方
split/array_split(array,indicate_or_seciont,axis): 用于指定切割方式,在切割的时候需要指定是按照行还是按照列, `axis=1`代表按照列,`axis=0`代表按照行
3| 数据的拼接
`vstack`:将数组按垂直方向进行叠加。数组的列数必须相同才能叠加
`hstack`:将数组按水平方向进行叠加。数组的行必须相同才能叠加
4| 数组广播(重点)
(1) 广播机制
1. 广播机制需要**扩展维度小的数组**, 使得它与维度最大的数组的shape值相同, 以便使用元素级函数或者运算符进行运算。
2. 广播机制实现了时两个或两个以上数组的运算,即使这些数组的shape不是完全相同的, 只需要满足如下任意一个条件即可。
- 1.数组的某一维度等长。
- 2.其中一个数组的某一维度为1 。 但是一旦出现了在某个维度下两个数据宽度不相等,并且两者全不为1的状况,就无法广播
(2) 通用函数
1| 一元函数
1| | 函数名 | 描述 | | ------------------------- | ------------------------------------------------------------ | | abs、fabs | 逐个元素地计算整数、浮点数或复数地绝对值 | | sqrt | 计算每个元素的平方根(与arr ** 0.5相等) | | square | 计算每个元素地平方(与arr ** 2相等) | | exp | 计算每个元素的自然指数值e^x次方 | | log、log10、log2、log1p | 分别对应(自然指数(e为底)、对数10为底、对数2为底、log(1+x)) | | sign | 计算每个元素的符号值:1(正数)、0(0)、-1(负数) | | ceil | 计算每个元素的最高整数值(即大于等于给定数值的最小整数) | | floor | 计算每个元素的最小整数值(即小于等于给定整数的最大整数) | | rint | 将元素保留到整数位,并保持dtype | | modf | 分别将数组的小数部分与整数部分按数组形式返回 | | isnan | 返回数组元素是否是一个NaN(非数值),形式为布尔值数组 | | isfinite、isinf | 分别返回数组中的元素是否有限(非inf、非NaN)、是否无限的,形式为布尔值数组 | | cos、cish、sin、 | 常规三角函数及双曲三角函数 | | sinh、tan、tanh | | | arccos、arccosh、arcsin、 | 反三角函数 | | arcsinh、arctan、arctanh | | | logical_not | 对数组元素按位取反(~) |
2| 二元函数
2| | 函数名 | 描述 | | ----------------------------|------------------------------------------------------------| | add | 将数组的对应元素相加 | | subtract | 在第二个数组中,将第一个数组中包含的元素去除 | | multiply | 将数组的对应元素相乘 | | divide,floor_divide | 除或整除(放弃余数) | | power | 将第二个数组的元素作为第一个数组对应元素的幂次方 | | maximum | 逐个元素计算最大值,fmax忽略NaN | | minimum | 逐个元素计算最小值,fmin忽略NaN | | mod | 按元素的求模计算(即求除法的余数) | | copysign | 将第一个数组的符号值改为第二个数组的符号值 | | greater,greater_equal,less, | 进行逐个元素的比较,返回布尔值数组(与数学操作符>,>=,<,<=,==,!=x效果一致) | | less_equal,equal,not_equal | (接上) | | logical_and,logical_or | 进行逐个元素的逻辑操作(与逻辑操作符&、丨、^效果一致) | | logical_xor | |
3| 聚合函数
4| 布尔数组函数
4| | 函数名 | 描述 | | ------ | ------------------------ | | any | 验证任意一个数据是否为真 | | all | 验证所有元素为真 |
5| 更多
4| pandas 官网
1. 基础
1. 导入 import pandas as pd
2. 数据读取与存储 官方文档
1| CSV
a. pd.read_csv 读取csv
pandas.read_csv(filepath_or_buffer, sep =',', usecols )
filepath_or_buffer:文件路径
sep :分隔符,默认用","隔开
usecols : 指定读取的列名,列表形式
encoding : 编码
参数
b. pd.to_csv 保存csv
DataFrame.to_csv( path_or_buf=None, sep=', ’,columns=None, header=True, index=True, mode='w',encoding=None)
path_or_buf : 文件路径
sep : 分隔符,默认用","隔开
columns : 选择需要的列索引
header : boolean or list of string, default True,是否写进列索引值
index : 是否写进行索引
mode : 'w':重写, 'a' 追加
参数
2| json
a. pd.read_json 读取json
b. 将JSON格式准换成默认的 Pandas DataFrame格式
orient : string,Indication of expected JSON string format.
split : dict like {index -> [index], columns -> [columns], data -> [values]}
split 将索引总结到索引,列名到列名,数据到数据。 将三部分都分开了
records : list like [{column -> value}, ... , {column -> value}]
records 以`columns:values`的形式输出
index : dict like {index -> {column -> value}}
index 以`index:{columns:values}...`的形式输出
columns : dict like {column -> {index -> value}}
默认该格式 colums 以`columns:{index:values}`的形式输出
lines : boolean, default False
按照每行读取json对象
typ : default ‘frame’, 指定转换成的对象类型series或者dataframe
c. pd.to_json 保存json
(1) DataFrame.to_json(path_or_buf=None, orient=None,lines=False)
1| 将Pandas 对象存储为json格式
2| orient:存储的json形式, {‘split’,’records’,’index’,’columns’,’values’}
3| path_or_buf=None*:文件地址
4| lines : 一个对象存储为一行
(2) 保存格式
a. split 结果见注释
a. { "columns":["name","job","address"], "index":[0,1,2,3,4,5,6,7,8,9], "data":[["邵帆","机修工","广西壮族自治区建国市花溪合肥街t座 303979"],["何丹丹","系统测试","湖北省沈阳市清城杨路b座 435741"],["范佳","汽车修理工","四川省建县丰都李街e座 707065"],["王云","服装\/纺织\/皮革工艺师","内蒙古自治区长沙市双滦巢湖路D座 438460"],["赵玉珍","ERP技术开发","吉林省玉华市崇文杨路l座 846818"],["倪阳","销售行政专员","甘肃省欢县怀柔重庆路H座 950331"],["成莉","麻醉医生","广西壮族自治区文市华龙余路q座 603504"],["任斌","其他","湖北省上海县东城长沙街D座 331924"],["赵霞","医疗器械注册","北京市燕市双滦澳门路I座 647751"],["黄莹","其他","福建省惠州县涪城王街j座 216044"]]}
b. index 结果见注释
b. { "0":{"name":"邵帆","job":"机修工","address":"广西壮族自治区建国市花溪合肥街t座 303979"}, "1":{"name":"何丹丹","job":"系统测试","address":"湖北省沈阳市清城杨路b座 435741"}, "2":{"name":"范佳","job":"汽车修理工","address":"四川省建县丰都李街e座 707065"}, "3":{"name":"王云","job":"服装\/纺织\/皮革工艺师","address":"内蒙古自治区长沙市双滦巢湖路D座 438460"}, "4":{"name":"赵玉珍","job":"ERP技术开发","address":"吉林省玉华市崇文杨路l座 846818"}, "5":{"name":"倪阳","job":"销售行政专员","address":"甘肃省欢县怀柔重庆路H座 950331"}, "6":{"name":"成莉","job":"麻醉医生","address":"广西壮族自治区文市华龙余路q座 603504"}, "7":{"name":"任斌","job":"其他","address":"湖北省上海县东城长沙街D座 331924"}, "8":{"name":"赵霞","job":"医疗器械注册","address":"北京市燕市双滦澳门路I座 647751"}, "9":{"name":"黄莹","job":"其他","address":"福建省惠州县涪城王街j座 216044"}}
c. table 结果见注释
c. { "name":{"0":"邵帆","1":"何丹丹","2":"范佳","3":"王云","4":"赵玉珍","5":"倪阳","6":"成莉","7":"任斌","8":"赵 霞","9":"黄莹"}, "job":{"0":"机修工","1":"系统测试","2":"汽车修理工","3":"服装\/纺织\/皮革工艺师","4":"ERP技术开发","5":"销售行政专 员","6":"麻醉医生","7":"其他","8":"医疗器械注册","9":"其他"}, "address":{"0":"广西壮族自治区建国市花溪合肥街t座 303979","1":"湖北省沈阳市清城杨路b座 435741","2":"四川省建县丰都李街e 座 707065","3":"内蒙古自治区长沙市双滦巢湖路D座 438460","4":"吉林省玉华市崇文杨路l座 846818","5":"甘肃省欢县 怀柔重庆路H座 950331","6":"广西壮族自治区文市华龙余路q座 603504","7":"湖北省上海县东城长沙街D座 331924","8":"北京市燕市双滦澳门路I座 647751","9":"福建省惠州县涪城王街j座 216044"} }
3| HDF5
3| **HDF5文件的读取和存储需要指定一个键,值为要存储的DataFrame** - pandas.read_hdf(path_or_buf,key =None,** kwargs) 从h5文件当中读取数据 - path_or_buffer:文件路径 - key:读取的键 - return:Theselected object - DataFrame.to_hdf(path_or_buf, *key*, **\*kwargs*) 需要安装安装tables模块避免不能读取HDF5文件
a. 安装 pip install tables
b. **HDF5文件的读取和存储需要指定一个键,值为要存储的DataFrame**
c. 读取 变量=pd.read_hdf("文件名")
d. 存储 变量.to_hdf("存储文件名", key="变量")
4| Excel
a. 读取
a. pd.read_excel('文件名', sheet_name='表1') # sheet_name可以是整型数字或者表的名字 pd.read_excel('文件名', sheet_name='表1', skiprows=[0, 1, 2]) # skiprows 跳过特定行 pd.read_excel('文件名', sheet_name='表1', nrows = 10) # nrows 需要读取的行数
b. 保存
b. df.to_excel('文件名.xlsx')
3. pandas 数据结构
a. Series的创建
a. pd.Series(data=None, index=None, dtype=None) 参数: - data:传入的数据,可以是ndarray、list等 - index:索引,必须是唯一的,且与数据的长度相等。如果没有传入索引参数,则默认会自动创建一个从0-N的整数索引。 - dtype:数据的类型
1| 通过已有数据创建
1| 指定内容,默认索引 pd.Series(np.arange(5)) # 运行结果 0 0 1 1 2 2 3 3 4 4 dtype: int64
2| 指定行索引名
2| ser3 = pd.Series(range(5), index=['a', 'b', 'c', 'd', 'e']) print(ser3) 运行结果: a 0 b 1 c 2 d 3 e 4 dtype: int64
3| 通过字典数据创建
3| ser4 = pd.Series({'red': 100, 'blue': 200, 'green': 500, 'yellow': 1000}) ser4 # 运行结果 blue 200 green 500 red 100 yellow 1000 dtype: int64
b. Series的属性
b. 为了更方便地操作Series对象中的索引和数据,Series中提供了两个属性index和values
1| index
1| ser4.index # 结果 Index(['blue', 'green', 'red', 'yellow'], dtype='object')
2| values
2| ser4.values # 结果 array([ 200, 500, 100, 1000]) 也可以使用索引来获取数据: ser4[2] # 结果 100
c. DataFrame
c. DataFrame是一个类似于二维数组或表格(如excel)的对象,既有行索引,又有列索引 - 行索引,表明不同行,横向索引,叫index,0轴,axis=0 - 列索引,表名不同列,纵向索引,叫columns,1轴,axis=1
1| DataFrame的创建
1| # 导入pandas import pandas as pd pd.DataFrame(data=None, index=None, columns=None) 参数: - index:行标签。如果没有传入索引参数,则默认会自动创建一个从0-N的整数索引。 - columns:列标签。如果没有传入索引参数,则默认会自动创建一个从0-N的整数索引。
a. 通过已有数据创建
a. pd.DataFrame(np.random.randn(2,3))
b. 增加行、列索引
b. """增加行列索引""" # 构造行索引序列 subjects = ["语文", "数学", "英语", "政治", "体育"] # 构造列索引序列 stu = ['同学' + str(i) for i in range(len(score))] # 添加行索引 students = pd.DataFrame(score, columns=subjects, index=stu) print('students:\n', students)
2| DataFrame的属性
a. shape
a. print('students.shape:\t', students.shape) # 结果 students.shape: (10, 5)
b. index DataFrame的行索引列表
b. print('students.index:\t', students.index) # 结果 students.index: Index(['同学0', '同学1', '同学2', '同学3', '同学4', '同学5', '同学6', '同学7', '同学8', '同学9'], dtype='object')
c. columns DataFrame的行索引列表
c. print('students.columns:\t', students.columns) # 结果 students.columns: Index(['语文', '数学', '英语', '政治', '体育'], dtype='object')
d. values 直接获取其中array的值
d. print('students.values:\n', students.values) # 结果 students.values: [[92 55 78 50 50] [71 76 50 48 96] [45 84 78 51 68] [81 91 56 54 76] [86 66 77 67 95] [46 86 56 61 99] [46 95 44 46 56] [80 50 45 65 57] [41 93 90 41 97] [65 83 57 57 40]]
e. T 转置
e. students.T 行、列索引倒置
f. tail(5):显示后5行内容 如果不补充参数,默认5行。 填入参数N则显示后N行
f. students.tail(5)
3| DataFrame索引
a. 修改行列索引值
a. stu = ["学生_" + str(i) for i in range(score_df.shape[0])] # 必须整体全部修改 data.index = stu 注意:以下修改方式是错误的 # 错误修改方式 data.index[3] = '学生_3'
b. 重设索引
b. reset_index(drop=False) - 设置新的下标索引 - drop:默认为False,不删除原来索引,如果为True,删除原来的索引值 # 重置索引,drop=False data.reset_index() # 重置索引,drop=True data.reset_index(drop=True)
c. 以某列值设置为新的索引
c. set_index(keys, drop=True) - **keys** : 列索引名成或者列索引名称的列表 - **drop** : boolean, default True.当做新的索引,删除原来的列
4. 索引对象
a. Index索引
a. 1.Series和DataFrame中的索引都是Index对象 代码: df = pd.DataFrame({'month': [1, 4, 7, 10], 'year': [2012, 2014, 2013, 2014], 'sale':[55, 40, 84, 31]}) se = pd.Series(np.arange(10)) df.index, se.index 结果: (RangeIndex(start=0, stop=4, step=1), RangeIndex(start=0, stop=10, step=1)) 2.索引对象不可变,保证了数据的安全 代码: # 索引对象不可变 df.index[0] = 2 结果: --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-23-7f40a356d7d1> in <module>() 1 # 索引对象不可变 ----> 2 df_obj2.index[0] = 2 /Users/Power/anaconda/lib/python3.6/site-packages/pandas/indexes/base.py in __setitem__(self, key, value) 1402 1403 def __setitem__(self, key, value): -> 1404 raise TypeError("Index does not support mutable operations") 1405 1406 def __getitem__(self, key): TypeError: Index does not support mutable operations
b. Pandas层级索引
b. 下面创建一个Series, 在输入索引Index时,输入了由两个子list组成的list,第一个子list是外层索引,第二个list是内层索引 代码: import pandas as pd import numpy as np ser_obj = pd.Series(np.random.randn(12),index=[ ['a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'c', 'd', 'd', 'd'], [0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2] ]) print(ser_obj) 结果: import pandas as pd import numpy as np ser_obj = pd.Series(np.random.randn(12),index=[ ['a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'c', 'd', 'd', 'd'], [0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2] ]) print(ser_obj)
c. MultiIndex索引对象
c. - 打印这个Series的索引类型,显示是MultiIndex - 直接将索引打印出来,可以看到有lavels,和labels两个信息。levels表示两个层级中分别有那些标签,labels是每个位置分别是什么标签。 代码: print(type(ser_obj.index)) print(ser_obj.index) 结果: <class 'pandas.indexes.multi.MultiIndex'> MultiIndex([('a', 0), ('a', 1), ('a', 2), ('b', 0), ('b', 1), ('b', 2), ('c', 0), ('c', 1), ('c', 2), ('d', 0), ('d', 1), ('d', 2)], )
取值
1.根据索引获取数据。因为现在有两层索引,当通过外层索引获取数据的时候,可以直接利用外层索引的标签来获取。 2.当要通过内层索引获取数据的时候,在list中传入两个元素,前者是表示要选取的外层索引,后者表示要选取的内层索引。
1| 外层选取
1| ser_obj['outer_label'] 代码: print(ser_obj['c']) 结果: 0 -1.362096 1 1.558091 2 -0.452313 dtype: float64
2| 内层选取
2| ser_obj[:, 'inner_label'] 代码: # 内层选取 print(ser_obj[:, 2]) 结果: a 0.826662 b 0.015426 c -0.452313 d -0.051063 dtype: float64 **常用于分组操作、透视表的生成等**
5. 小结
5. - pandas的优势【了解】 - 增强图表可读性 - 便捷的数据处理能力 - 读取文件方便 - 封装了Matplotlib、Numpy的画图和计算 - series【知道】 - 创建 - pd.Series([], index=[]) - pd.Series({}) - 属性 - 对象.index - 对象.values - DataFrame【掌握】 - 创建 - pd.DataFrame(data=None, index=None, columns=None) - 属性 - shape -- 形状 - index -- 行索引 - columns -- 列索引 - values -- 查看值 - T -- 转置 - head() -- 查看头部内容 - tail() -- 查看尾部内容 - DataFrame索引 - 修改的时候,需要进行全局修改 - 对象.reset_index() - 对象.set_index(keys) - MultiIndex【了解】 - multiIndex: - 类似ndarray中的三维数组 - 创建: - pd.MultiIndex.from_arrays() - 属性: - 对象.index
6. 基本操作总结
6. - 1.索引【掌握】 - 直接索引 -- 先列后行,是需要通过索引的字符串进行获取 - loc -- 先行后列,是需要通过索引的字符串进行获取 - iloc -- 先行后列,是通过下标进行索引 - 2.赋值【知道】 - data[""] = ** - data. **=** - 3.排序【知道】 - dataframe - 对象.sort_values() - 对象.sort_index() - series - 对象.sort_values() - 对象.sort_index()
2. 索引排序及计算
a. 基本操作
1| 索引操作
1| Numpy当中我们已经讲过使用索引选取序列和切片选择,pandas也支持类似的操作,也可以直接使用列名、行名 称,甚至组合使用
1| 直接使用行列索引(先列后行)
2| 结合loc或者iloc使用索引
2| 赋值操作
2| 对DataFrame当中的close列进行重新赋值为1 # 直接修改原来的值 df['close'] = 1 # 或者 df.close = 1 print(df.close)
3| 排序
3| 排序有两种形式,一种对于索引进行排序,一种对于内容进行排序
1| DataFrame 排序
1| - 使用df.sort_values(by=, ascending=) - 单个键或者多个键进行排序, - 参数: - by:指定排序参考的键 - ascending:默认升序 - ascending=False:降序 - ascending=True:升序
2| Series排序
2| - 使用series.sort_values(ascending=True)进行排序 series排序时,只有一列,不需要参数 使用series.sort_index()进行排序
4| 总结
4| - 1.索引【掌握】 - 直接索引 -- 先列后行,是需要通过索引的字符串进行获取 - loc -- 先行后列,是需要通过索引的字符串进行获取 - iloc -- 先行后列,是通过下标进行索引 - 2.赋值【知道】 - data[""] = ** - data. **=** - 3.排序【知道】 - dataframe - 对象.sort_values() - 对象.sort_index() - series - 对象.sort_values() - 对象.sort_index()
b. DataFrame运算
1| 算术运算
1| 比如进行数学运算加上具体的一个数字 - add(other) - sub(other)
2| 逻辑运算
2| #### 逻辑运算符号 - 例如筛选data["open"] > 23的日期数据 - data["open"] > 23返回逻辑结果 # 逻辑判断的结果可以作为筛选的依据 print(df[df['open'] > 23].head())
3| 逻辑运算函数
3| query(expr) expr:查询字符串 通过query使得刚才的过程更加方便简单 print(df.query("open<24 & open>23").head()) isin(values)
4| 统计运算
(1) describe
(1) 综合分析: 能够直接得出很多统计结果,`count`, `mean`, `std`, `min`, `max` 等 # 计算平均值、标准差、最大值、最小值 df.describe()
(2) 统计函数
(2) 对于单个函数去进行统计的时候,坐标轴还是按照默认列“columns” (axis=0, default),如果要对行“index” 需要指定(axis=1) | `count` | Number of non-NA observations | | -------- | ---------------------------------------------- | | `sum` | **Sum of values** | | `mean` | **Mean of values** | | `median` | Arithmetic median of values 中位数 | **中位数为将数据从小到大排列,在最中间的那个数为中位数。如果没有中间数,取中间两个数的平均值。 | `min` | **Minimum** 最小值 | | `max` | **Maximum** 最大值 | | `mode` | Mode | | `abs` | Absolute Value | | `prod` | Product of values | | `std` | **Bessel-corrected sample standard deviation** | 标准差 | `var` | **Unbiased variance** 方差 | | `idxmax` | compute the index labels with the maximum | 求出最大值的位置 | `idxmin` | compute the index labels with the minimum | 求出最小值的位置
(3) 累计统计函数
(3) | 函数 | 作用 | | --------- | --------------------------- | | `cumsum` | **计算前1/2/3/…/n个数的和** | | `cummax` | 计算前1/2/3/…/n个数的最大值 | | `cummin` | 计算前1/2/3/…/n个数的最小值 | | `cumprod` | 计算前1/2/3/…/n个数的积 |
5| 小结
5| - 算术运算【知道】 - 逻辑运算【知道】 - 1.逻辑运算符号 - 2.逻辑运算函数 - 对象.query() - 对象.isin() - 统计运算【知道】 - 1.对象.describe() - 2.统计函数 - 3.累积统计函数
3. 数据清洗
a. 数据质量的准则 4个关键点--“完全合一”
1. 完整性:单条数据是否存在空值,统计的字段是否完善。
2. 全面性:观察某一列的全部数值, 比如在Excel表中,我们选中一列,可以看到该列的平均值、最大值、最小值。 我们可以通过常识来判断该列是否有问题,比如:数据定义、单位标识、数值本身。
3. 合法性:数据的类型、内容、大小的合法性。 比如数据中存在非ASCII字符,性别存在了未知,年龄超过了150岁等。
4. 唯一性:数据是否存在重复记录,因为数据通常来自不同渠道的汇总,重复的情况是常见的。行数据、列数据都需要是唯一的,比如一个人不能重复记录多次,且一个人的体重也不能在列指标中重复记录多次。
b. 处理缺失数据
(1) 缺失值
(1) 在数据表或 DataFrame 中有很多识别缺失值的方法。一般情况下可以分为两种:一种方法是通过一个覆盖全局的掩码表示缺失值,另一种方法是用一个标签值(sentinel value)表示缺失值。在掩码方法中,掩码可能是一个与原数组维度相同的完整布尔类型数组,也可能是用一个比特(0 或 1)表示有缺失值的局部状态。 在标签方法中,标签值可能是具体的数据(例如用 -9999 表示缺失的整数),也可能是些极少出现的形式。另外,标签值还可能是更全局的值,比如用 NaN(不是一个数)表示缺失的浮点数
1| None:Python对象类型的缺失值
1| import numpy as np # None np_arr = np.array([1, None, 3, 4]) print(np_arr)
2| NaN:数值类型的缺失值
3| Pandas中NaN与None的差异
3| 虽然 NaN 与 None 各有各的用处,但是 Pandas 把它们看成是可以等价交换的,在适当的时候会将两者进行替换: # NaN与 None的差异 ser = pd.Series([1, np.nan, 2, None]) print(ser) """ 0 1.0 1 NaN 2 2.0 3 NaN dtype: float64 """ Pandas 会将没有标签值的数据类型自动转换为 NA。 ser2 = pd.Series(range(2), dtype=int) ser2[0] = None print(ser2) """ 0 NaN 1 1.0 dtype: float64 """
4| Pandas对不同类型缺失值的转换规则
4| | 类型 | 缺失值转换规则 | NA标签值 | | ------------------- | ------------------------- | -------------- | | floating 浮点型 | 无变化 | np.nan | | object 对象类型 | 无变化 | None 或 np.nan | | integer 整数类型 | 强制转换为 float64 | np.nan | | boolean 布尔类型 | 强制转换为 object | None 或 np.nan | 需要注意的是,Pandas 中字符串类型的数据通常是用 object 类型。
(2) 处理缺失数据
a. 方法及说明
| 方法 | 说明 |
| isnull() | 创建一个布尔类型的掩码标签缺失值。 |
| notnull() | 与 isnull() 操作相反。 |
判断空值
| dropna() | 返回一个剔除缺失值的数据。 |
| fillna() | 返回一个填充了缺失值的数据副本。 |
b. 判断空值 isnull() 和 notnull()
c. 剔除缺失值 dropna()方法
d. 填充缺失值 fillna() 方法
c. 重复数据
c. | 方法 | 说明 | | ----------------- | ------------------------------------ | | duplicated() | 返回布尔型Series表示每行是否为重复行 | | drop_duplicates() | 删除重复数据 |
(1) 处理重复数据
(1) import numpy as np import pandas as pd """重复行""" df = pd.DataFrame({ 'brand': ['Yum Yum', 'Yum Yum', 'Indomie', 'Indomie', 'Indomie', 'Indomie'], 'style': ['cup', 'cup', 'cup', 'pack', 'pack', 'pack'], 'rating': [4, 4, 3.5, 15, 5, 5] }) # 判断重复行,默认保留第一个 print(df.duplicated()) # 判断重复行,保留最后一个 print('保留最后一个:\n', df.duplicated(keep='last')) # 所有的重复行全部标注出来 print('全部标注:\n', df.duplicated(keep=False)) # 获取指定列的重复行 print('指定列:\n', df.duplicated(subset=['brand']))
(2) 过滤重复行
(2) drop_duplicates() - 默认判断全部列 - 可指定按某些列判断
d. 数据替换
(1) 替换值
1| replace根据值的内容进行替换
2| 正则替换
2| import pandas as pd """正则表达式替换""" df = pd.DataFrame({'A': ['bat', 'foo', 'bait'], 'B': ['abc', 'bar', 'xyz']}) print(df) # 替换内容 print(df.replace(to_replace=r'^ba.$', value='new', regex=True)) # 字典替换 print(df.replace({'A': r'^ba.$'}, {'A': 'new'}, regex=True)) print(df.replace(regex=r'^ba.$', value='new')) print(df.replace(regex={r'^ba.$': 'new', 'foo': 'xyz'})) print(df.replace(regex=[r'^ba.$', 'foo'], value='new'))
(2) 函数数据替换
1| map
1| 根据map传入的函数对每行或每列进行转换 s = pd.Series(['cat', 'dog', np.nan, 'rabbit']) print(s) # 指定字典进行替换,没有指定的内容替换为空 print(s.map({'cat': 'kitten', 'dog': 'puppy'})) print(s) # 指定方法进行替换 print(s.map(lambda x: 'I am a {}'.format(x))) def func(temp): return 'I am a {}'.format(temp) # 将缺失值忽略替换 print(s.map(func, na_action='ignore'))
2| apply
2| apply 将函数应用到列或行上 - apply(func, axis=0) - func:自定义函数 - axis=0:默认是列,axis=1为行进行运算 - 定义一个对列,最大值-最小值的函数 df = pd.DataFrame(np.random.randn(5,4)) df # apply将函数应用到行或者列 def f(x): return x.max() # 默认应用在行上 df.apply(f) # 默认axis=0 # 替换行 print('替换行\n', df.apply(replace_line, axis=1)) # 将返回的行数据进行展开 print('替换行-展开\n', df.apply(replace_line, axis=1, result_type='expand'))
3| applymap
3| applymap 将函数应用到每个数据 """批量操作数据 针对每一个元素""" df = pd.DataFrame([[1, 2.12], [3.356, 4.567]]) print(df) print(df.applymap(lambda x: '%.2f' % x))
e. 字符串操作
(1) 字符串方法
(2) 正则表达式方法
(3) pandas字符串函数
4. 分组聚合与时间序列
A. 分组聚合
A. groupby:(by=None,as_index=True) by:根据什么进行分组,用于确定groupby的组** as_index:对于聚合输出,返回以组便签为索引的对象,仅对DataFrame
a. GroupBy对象
a. GroupBy 中最重要的操作可能就是 **aggregate**、**filter**、**transform** 和 **apply**(累计、过滤、转换、应用)了
b. 聚合(agg)
c. 过滤(filter)
B. 数据合并(知道)
a. 数据合并(pd.merge)
a. 数据合并(pd.merge) 根据单个或多个键将不同DataFrame的行连接起来 类似数据库的连接操作 pd.merge:(left, right, how='inner',on=None,left_on=None, right_on=None ) 参数: left:合并时左边的DataFrame right:合并时右边的DataFrame how:合并的方式,默认'inner', 'outer', 'left', 'right' on:需要合并的列名,必须两边都有的列名,并以 left 和 right 中的列名的交集作为连接键 left_on: left Dataframe中用作连接键的列 right_on: right Dataframe中用作连接键的列
(1) 内连接 inner:对两张表都有的键的交集进行联合 两者相交的地方
(2) 全连接 outer:对两者表的都有的键的并集进行联合 全部
(3) 左连接 left:对所有左表的键进行联合 左边全部
(4) 右连接 right:对所有右表的键进行联合 右边全部
示例代码及结果 见注释
代码: import pandas as pd import numpy as np left = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'], 'A': ['A0', 'A1', 'A2', 'A3'], 'B': ['B0', 'B1', 'B2', 'B3']}) right = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'], 'C': ['C0', 'C1', 'C2', 'C3'], 'D': ['D0', 'D1', 'D2', 'D3']}) pd.merge(left,right,on='key') #指定连接键key 运行结果: key A B C D 0 K0 A0 B0 C0 D0 1 K1 A1 B1 C1 D1 2 K2 A2 B2 C2 D2 3 K3 A3 B3 C3 D3
(5) 处理重复列名
(5) 参数suffixes:默认为_x, _y
(6) 按索引连接
(6) 参数left_index=True或right_index=True
b. 数据合并(pd.concat)
b. 沿轴方向将多个对象合并到一起
(1) NumPy的concat
(1) 代码: import numpy as np import pandas as pd arr1 = np.random.randint(0, 10, (3, 4)) arr2 = np.random.randint(0, 10, (3, 4)) print(arr1) print(arr2) print(np.concatenate([arr1, arr2])) print(np.concatenate([arr1, arr2], axis=1)) 结果: # print(arr1) [[3 3 0 8] [2 0 3 1] [4 8 8 2]] # print(arr2) [[6 8 7 3] [1 6 8 7] [1 4 7 1]] # print(np.concatenate([arr1, arr2])) [[3 3 0 8] [2 0 3 1] [4 8 8 2] [6 8 7 3] [1 6 8 7] [1 4 7 1]] # print(np.concatenate([arr1, arr2], axis=1)) [[3 3 0 8 6 8 7 3] [2 0 3 1 1 6 8 7] [4 8 8 2 1 4 7 1]]
(2) pd.concat
(2) - 注意指定轴方向,默认axis=0 - join指定合并方式,默认为outer - Series合并时查看行索引有无重复
c. 重塑
(1) stack
(1) - 将列索引旋转为行索引,完成层级索引 - DataFrame->Series
(2) unstack
(2) - 将层级索引展开 - Series->DataFrame - 默认操作内层索引,即level=1
C. 时间序列
C. - 时间戳(timestamp),特定的时刻。 - 固定时期(period),如2007年1月或2010年全年。 - 时间间隔(interval),由起始和结束时间戳表示。时期(period)可以被看做间隔(interval)的特例
时间和日期数据类型
(1) datetime
(1) 导入:from datetime import datetime datetime以毫秒形式存储日期和时间。timedelta表示两个datetime对象之间的时间差: 示例代码: In [14]: delta = datetime(2011, 1, 7) - datetime(2008, 6, 24, 8, 15) In [15]: delta Out[15]: datetime.timedelta(926, 56700) In [16]: delta.days Out[16]: 926 In [17]: delta.seconds Out[17]: 56700 可以给datetime对象加上(或减去)一个或多个timedelta,这样会产生一个新对象: 示例代码: In [18]: from datetime import timedelta In [19]: start = datetime(2011, 1, 7) In [20]: start + timedelta(12) Out[20]: datetime.datetime(2011, 1, 19, 0, 0) In [21]: start - 2 * timedelta(12) Out[21]: datetime.datetime(2010, 12, 14, 0, 0)
(2) 字符串和datetime的相互转换
(2) 利用str或strftime方法(传入一个格式化字符串),datetime对象和pandas的Timestamp对象(稍后就会介绍)可以被格式化为字符串
时间序列
| 符号 | 含义 | 例 | | ---- | ------------------------------------- | ---------------------------- | | `%a` | 缩写的工作日名称 | `'Wed'` | | `%A` | 完整的工作日名称 | `'Wednesday'` | | `%w` | 工作日编号 - 0(星期日)至6(星期六) | `'3'` | | `%d` | 每月的一天(零填充) | `'13'` | | `%b` | 缩写的月份名称 | `'Jan'` | | `%B` | 全月名称 | `'January'` | | `%m` | 一年中的一个月 | `'01'` | | `%y` | 没有世纪的一年 | `'16'` | | `%Y` | 与世纪的一年 | `'2016'` | | `%H` | 24小时制的小时 | `'17'` | | `%I` | 12小时制的小时 | `'05'` | | `%p` | 上午下午 | `'PM'` | | `%M` | 分钟 | `'00'` | | `%S` | 秒 | `'00'` | | `%f` | 微秒 | `'000000'` | | `%z` | 时区感知对象的UTC偏移量 | `'-0500'` | | `%Z` | 时区名称 | `'EST'` | | `%j` | 一年中的某一天 | `'013'` | | `%W` | 一年中的一周 | `'02'` | | `%c` | 当前区域设置的日期和时间表示形式 | `'Wed Jan 13 17:00:00 2016'` | | `%x` | 当前区域设置的日期表示形式 | `'01/13/16'` | | `%X` | 当前区域设置的时间表示 | `'17:00:00'` | | `%%` | 文字`%`字符 | `'%'` || 符号 | 含义 | 例 | | ---- | ------------------------------------- | ---------------------------- | | `%a` | 缩写的工作日名称 | `'Wed'` | | `%A` | 完整的工作日名称 | `'Wednesday'` | | `%w` | 工作日编号 - 0(星期日)至6(星期六) | `'3'` | | `%d` | 每月的一天(零填充) | `'13'` | | `%b` | 缩写的月份名称 | `'Jan'` | | `%B` | 全月名称 | `'January'` | | `%m` | 一年中的一个月 | `'01'` | | `%y` | 没有世纪的一年 | `'16'` | | `%Y` | 与世纪的一年 | `'2016'` | | `%H` | 24小时制的小时 | `'17'` | | `%I` | 12小时制的小时 | `'05'` | | `%p` | 上午下午 | `'PM'` | | `%M` | 分钟 | `'00'` | | `%S` | 秒 | `'00'` | | `%f` | 微秒 | `'000000'` | | `%z` | 时区感知对象的UTC偏移量 | `'-0500'` | | `%Z` | 时区名称 | `'EST'` | | `%j` | 一年中的某一天 | `'013'` | | `%W` | 一年中的一周 | `'02'` | | `%c` | 当前区域设置的日期和时间表示形式 | `'Wed Jan 13 17:00:00 2016'` | | `%x` | 当前区域设置的日期表示形式 | `'01/13/16'` | | `%X` | 当前区域设置的时间表示 | `'17:00:00'` | | `%%` | 文字`%`字符 | `'%'` |
1| datetime.strptime 可以用这些格式化编码将字符串转换为日期
1| In [26]: datetime.strptime(value, '%Y-%m-%d') Out[26]: datetime.datetime(2011, 1, 3, 0, 0) In [27]: datestrs = ['7/6/2011', '8/6/2011'] In [28]: [datetime.strptime(x, '%m/%d/%Y') for x in datestrs] Out[28]: [datetime.datetime(2011, 7, 6, 0, 0), datetime.datetime(2011, 8, 6, 0, 0)]
2| datetime.strptime是通过已知格式进行日期解析的最佳方式。 但是每次都要编写格式定义是很麻烦的事情,尤其是对于一些常见的日期格式。 这种情况下,你可以用dateutil这个第三方包中的parser.parse方法(pandas中已经自动安装好了)
2| In [29]: from dateutil.parser import parse In [30]: parse('2011-01-03') Out[30]: datetime.datetime(2011, 1, 3, 0, 0)
3| dateutil 可以解析几乎所有人类能够理解的日期表示形式
3| In [31]: parse('Jan 31, 1997 10:45 PM') Out[31]: datetime.datetime(1997, 1, 31, 22, 45)
4| 在国际通用的格式中,日出现在月的前面很普遍,传入dayfirst=True即可解决这个问题:
4| In [32]: parse('6/12/2011', dayfirst=True) Out[32]: datetime.datetime(2011, 12, 6, 0, 0)
5| pandas通常是用于处理成组日期的, 不管这些日期是DataFrame的轴索引还是列。 to_datetime方法可以解析多种不同的日期表示形式。 对标准日期格式(如ISO8601)的解析非常快
5| In [33]: datestrs = ['2011-07-06 12:00:00', '2011-08-06 00:00:00'] In [34]: pd.to_datetime(datestrs) Out[34]: DatetimeIndex(['2011-07-06 12:00:00', '2011-08-06 00:00:00'], dtype='dat etime64[ns]', freq=None)
6| 它还可以处理缺失值(None、空字符串等)
6| In [35]: idx = pd.to_datetime(datestrs + [None]) In [36]: idx Out[36]: DatetimeIndex(['2011-07-06 12:00:00', '2011-08-06 00:00:00', 'NaT'], dty pe='datetime64[ns]', freq=None) In [37]: idx[2] Out[37]: NaT In [38]: pd.isnull(idx) Out[38]: array([False, False, True], dtype=bool)
7| NaT(Not a Time) 是pandas中时间戳数据的null值。
(3) 时间序列基础
1| pandas最基本的时间序列类型就是以时间戳 (通常以Python字符串或datatime对象表示)为索引的Series
1| In [39]: from datetime import datetime In [40]: dates = [datetime(2011, 1, 2), datetime(2011, 1, 5), ....: datetime(2011, 1, 7), datetime(2011, 1, 8), ....: datetime(2011, 1, 10), datetime(2011, 1, 12)] In [41]: ts = pd.Series(np.random.randn(6), index=dates) In [42]: ts Out[42]: 2011-01-02 -0.204708 2011-01-05 0.478943 2011-01-07 -0.519439 2011-01-08 -0.555730 2011-01-10 1.965781 2011-01-12 1.393406 dtype: float64
2| 这些datetime对象实际上是被放在一个DatetimeIndex中的
2| In [43]: ts.index Out[43]: DatetimeIndex(['2011-01-02', '2011-01-05', '2011-01-07', '2011-01-08', '2011-01-10', '2011-01-12'], dtype='datetime64[ns]', freq=None)
3| 跟其他Series一样,不同索引的时间序列之间的算术运算会自动按日期对齐:
3| In [44]: ts + ts[::2] Out[44]: 2011-01-02 -0.409415 2011-01-05 NaN 2011-01-07 -1.038877 2011-01-08 NaN 2011-01-10 3.931561 2011-01-12 NaN dtype: float64 ts[::2] 是每隔两个取一个
(4) 索引、选取、子集构造
1| 当你根据标签索引选取数据时, 时间序列和其它的pandas.Series很像
1| In [48]: stamp = ts.index[2] In [49]: ts[stamp] Out[49]: -0.51943871505673811
2| 还有一种更为方便的用法: 传入一个可以被解释为日期的字符串:
2| In [50]: ts['1/10/2011'] Out[50]: 1.9657805725027142 In [51]: ts['20110110'] Out[51]: 1.9657805725027142
(5) 日期的范围、频率以及移动
(5) | 码 | 说明 | | ---- | ----------------------------------------- | | D | 天(calendar day,按日历算,含双 休日)周 | | W | 周(weekly) | | M | 月末(month end) | | Q | 季末(quarter end) | | A | 年末(year end) | | H | 小时(hours) | | T | 分钟(minutes) | | S | 秒(seconds) | | L | 毫秒(milliseonds) | | U | 微秒(microseconds) | | N | 纳秒(nanoseconds) | | B | 天(business day,仅含工作日) | | BM | 月末(business month end,仅含工作日) | | BQ | 季末(business quarter end,仅含工作日) | | BA | 年末(business year end,仅含工作日) | | BH | 小时(business hours,工作时间) |
(6) 生成日期范围
1| pandas.date_range 可用于根据指定的频率生成指定长度的 DatetimeIndex
1| In [74]: index = pd.date_range('2012-04-01', '2012-06-01') In [75]: index Out[75]: DatetimeIndex(['2012-04-01', '2012-04-02', '2012-04-03', '2012-04-04', '2012-04-05', '2012-04-06', '2012-04-07', '2012-04-08', '2012-04-09', '2012-04-10', '2012-04-11', '2012-04-12', '2012-04-13', '2012-04-14', '2012-04-15', '2012-04-16', '2012-04-17', '2012-04-18', '2012-04-19', '2012-04-20', '2012-04-21', '2012-04-22', '2012-04-23', '2012-04-24', '2012-04-25', '2012-04-26', '2012-04-27', '2012-04-28', '2012-04-29', '2012-04-30', '2012-05-01', '2012-05-02', '2012-05-03', '2012-05-04', '2012-05-05', '2012-05-06', '2012-05-07', '2012-05-08', '2012-05-09', '2012-05-10', '2012-05-11', '2012-05-12', '2012-05-13', '2012-05-14', '2012-05-15', '2012-05-16', '2012-05-17', '2012-05-18', '2012-05-19', '2012-05-20', '2012-05-21', '2012-05-22', '2012-05-23', '2012-05-24', '2012-05-25', '2012-05-26', '2012-05-27', '2012-05-28', '2012-05-29', '2012-05-30', '2012-05-31', '2012-06-01'], dtype='datetime64[ns]', freq='D')
2| date_range会产生按天计算的时间点。 如果只传入起始或结束日期,那就还得传入一个表示一段时间的数字
2| In [76]: pd.date_range(start='2012-04-01', periods=20) Out[76]: DatetimeIndex(['2012-04-01', '2012-04-02', '2012-04-03', '2012-04-04', '2012-04-05', '2012-04-06', '2012-04-07', '2012-04-08', '2012-04-09', '2012-04-10', '2012-04-11', '2012-04-12', '2012-04-13', '2012-04-14', '2012-04-15', '2012-04-16', '2012-04-17', '2012-04-18', '2012-04-19', '2012-04-20'], dtype='datetime64[ns]', freq='D') In [77]: pd.date_range(end='2012-06-01', periods=20) Out[77]: DatetimeIndex(['2012-05-13', '2012-05-14', '2012-05-15', '2012-05-16', '2012-05-17', '2012-05-18', '2012-05-19', '2012-05-20', '2012-05-21', '2012-05-22', '2012-05-23', '2012-05-24', '2012-05-25', '2012-05-26', '2012-05-27','2012-05-28', '2012-05-29', '2012-05-30', '2012-05-31', '2012-06-01'], dtype='datetime64[ns]', freq='D')
3| 起始和结束日期定义了日期索引的严格边界。
3| In [78]: pd.date_range('2000-01-01', '2000-12-01', freq='BM') Out[78]: DatetimeIndex(['2000-01-31', '2000-02-29', '2000-03-31', '2000-04-28', '2000-05-31', '2000-06-30', '2000-07-31', '2000-08-31', '2000-09-29', '2000-10-31', '2000-11-30'], dtype='datetime64[ns]', freq='BM')
(7) 重采样及频率转换 resample是一个灵活高效的方法, 可用于处理非常大的时间序列。
(7) pandas对象都带有一个resample方法,它是各种频率转换工作的主力函数。resample有一个类似于groupby的API,调用resample可以分组数据,然后会调用一个聚合函数: In [208]: rng = pd.date_range('2000-01-01', periods=100, freq='D') In [209]: ts = pd.Series(np.random.randn(len(rng)), index=rng) In [210]: ts Out[210]: 2000-01-01 0.631634 2000-01-02 -1.594313 2000-01-03 -1.519937 2000-01-04 1.108752 2000-01-05 1.255853 2000-01-06 -0.024330 2000-01-07 -2.047939 2000-01-08 -0.272657 2000-01-09 -1.692615 2000-01-10 1.423830 ... 2000-03-31 -0.007852 2000-04-01 -1.638806 2000-04-02 1.401227 2000-04-03 1.758539 2000-04-04 0.628932 2000-04-05 -0.423776 2000-04-06 0.789740 2000-04-07 0.937568 2000-04-08 -2.253294 2000-04-09 -1.772919 Freq: D, Length: 100, dtype: float64 In [211]: ts.resample('M').mean() Out[211]: 2000-01-31 -0.165893 2000-02-29 0.078606 2000-03-31 0.223811 2000-04-30 -0.063643 Freq: M, dtype: float64 In [212]: ts.resample('M', kind='period').mean() Out[212]: 2000-01 -0.165893 2000-02 0.078606 2000-03 0.223811 2000-04 -0.063643 Freq: M, dtype: float64
5| pyecharts 官方文档
1. 动态可视化
A. 安装 pip install pyecharts
B. 查看版本号 pyecharts.__version__
C. 版本 两者不兼容
1| 两个版本
a. v1
b. v0.5.X
2| 支持链式调用
D. 导入
(1) import pyecharts
(2) from pyecharts.charts import Bar 功能导入(Bar为柱状图)
E. 可以使用 jupyter notebook
2. 全局配置项
6| seaborn
图形
频次直方图 sns.jointplot sns.set() KDE核密度图 sns.jointplot sns.kdeplot 矩阵图 (pairplot) sns.pairplot 分面频次直方图 FacetGrid sns.FacetGrid 箱线图 (factor plot) sns.catplot 联合分布 sns.jointplot