admin 管理员组

文章数量: 1184232

# # 证书 #

本文将被收录在 打卡系列专栏,更多相关文章可以在里面查找

导读

在掌握了一些pandas的操作之后,怎样给表格数据保存下来是一个绕不开的问题。本次文章我们就来讨论pandas常见的文件读写IO。在此之前我们先进一步认识一下滑动窗口,滑动窗口在时间序列数据分析中出席率不低,例如判定季节入冬就需要滑动平均气温的计算,用滑动窗口就可以轻松解决。

滑动窗口

.rolling()方法在前面的文章中有所提及,这次来进一步加深了解。虽然说滑动窗口经常用于时间序列数据,但对于普通的Series也是可以使用的

import pandas as pd
data = {'column': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]}
df = pd.DataFrame(data)
df
    column
 0       1
 1       2
 2       3
 3       4
 4       5
 5       6
 6       7
 7       8
 8       9
 9      10

这是一个DataFrame,我们选取一列作为Series然后应用均值函数

df['MA'] = df['column'].rolling(window=3).mean()
df
    column   MA
 0       1  NaN
 1       2  NaN
 2       3  2.0
 3       4  3.0
 4       5  4.0
 5       6  5.0
 6       7  6.0
 7       8  7.0
 8       9  8.0
 9      10  9.0

通过传递参数window=3来设定滑动窗口的大小。

接下来分别应用聚合函数求和、最大值、最小值和标准差

df['SUM'] = df['column'].rolling(window=5).sum()
df['MAX'] = df['column'].rolling(window=7).max()
df['MIN'] = df['column'].rolling(window=7).min()
df['STD'] = df['column'].rolling(window=5).std()
df
    column   MA   SUM   MAX  MIN       STD
 0       1  NaN   NaN   NaN  NaN       NaN
 1       2  NaN   NaN   NaN  NaN       NaN
 2       3  2.0   NaN   NaN  NaN       NaN
 3       4  3.0   NaN   NaN  NaN       NaN
 4       5  4.0  15.0   NaN  NaN  1.581139
 5       6  5.0  20.0   NaN  NaN  1.581139
 6       7  6.0  25.0   7.0  1.0  1.581139
 7       8  7.0  30.0   8.0  2.0  1.581139
 8       9  8.0  35.0   9.0  3.0  1.581139
 9      10  9.0  40.0  10.0  4.0  1.581139

根据滑动窗口大小的不一样返回空值的个数也有所差异。

当然自定义聚合函数也是可以的,我们再次拿出自定义的平均绝对偏差函数

import numpy as np
def mad(x):
    return np.sum(np.abs(x - x.mean())) / len(x)
df['MAD'] = df['column'].rolling(window=3).apply(mad)
df
    column   MA   SUM   MAX  MIN       STD       MAD
 0       1  NaN   NaN   NaN  NaN       NaN       NaN
 1       2  NaN   NaN   NaN  NaN       NaN       NaN
 2       3  2.0   NaN   NaN  NaN       NaN  0.666667
 3       4  3.0   NaN   NaN  NaN       NaN  0.666667
 4       5  4.0  15.0   NaN  NaN  1.581139  0.666667
 5       6  5.0  20.0   NaN  NaN  1.581139  0.666667
 6       7  6.0  25.0   7.0  1.0  1.581139  0.666667
 7       8  7.0  30.0   8.0  2.0  1.581139  0.666667
 8       9  8.0  35.0   9.0  3.0  1.581139  0.666667
 9      10  9.0  40.0  10.0  4.0  1.581139  0.666667

文件读写IO

接下来我们主要来了解pandas的一些文件读写。其实用法已经很直观了基本上都是调用df.to_xxx()的形式就能够生成对应格式的文件。但是对于一些新搭建的环境,可能有一些依赖库没有安装到位,造成代码报错,不过没关系,在命令行中用pip安装就可以了。

csv文件

首先是最无痛的格式csv文件

import pandas as pd
import numpy as np
data = np.random.rand(10, 10)
columns = ['col' + str(i) for i in range(10)]
df = pd.DataFrame(data, columns=columns)
df
col0 col1 col2 col3 col4 col5 col6 col7 col8 col9
0 0.188838 0.242863 0.009761 0.263796 0.819400 0.219437 0.376219 0.109041 0.483579 0.137196
1 0.537111 0.412955 0.845320 0.900356 0.500164 0.136346 0.055736 0.342375 0.780777 0.797048
2 0.485815 0.638531 0.050680 0.632832 0.489002 0.090346 0.176374 0.241429 0.478637 0.052445
3 0.428487 0.176745 0.872160 0.572617 0.800724 0.096999 0.164391 0.076367 0.743757 0.224184
4 0.499604 0.384929 0.603271 0.950407 0.972324 0.662994 0.276461 0.207285 0.834498 0.918623
5 0.807182 0.345502 0.569022 0.191493 0.838638 0.142537 0.043660 0.797646 0.641671 0.661995
6 0.224364 0.117547 0.253472 0.800650 0.791210 0.662992 0.933724 0.982474 0.090368 0.848594
7 0.734468 0.164604 0.298378 0.037531 0.724353 0.976387 0.468621 0.428513 0.197949 0.995767
8 0.063096 0.463065 0.741885 0.302953 0.132439 0.706685 0.922946 0.336356 0.536714 0.288952
9 0.230219 0.353117 0.108670 0.385579 0.221161 0.118600 0.242965 0.544143 0.578594 0.983323
import os
path = os.path.join('.', 'output')
os.makedirs(path, exist_ok=True)
df.to_csv(r'./output/foo.csv', index=False)
  • 代码解读tips:前三行代码是为了在当前目录下创建一个output文件夹,pandas的输出路径如果不存在的话是会报错的。而路径字符串前缀r是使用原始文本,这是针对反斜杠功能而设置的避免windows系统路径的反斜杠被识别成Python的转义字符。最后index=False是去掉df中的行索引。

现在检查当前目录下的output文件夹,应该能发现一个foo.csv文件。

读取也是一个函数的事情

pd.read_csv(r'./output/foo.csv')
col0 col1 col2 col3 col4 col5 col6 col7 col8 col9
0 0.188838 0.242863 0.009761 0.263796 0.819400 0.219437 0.376219 0.109041 0.483579 0.137196
1 0.537111 0.412955 0.845320 0.900356 0.500164 0.136346 0.055736 0.342375 0.780777 0.797048
2 0.485815 0.638531 0.050680 0.632832 0.489002 0.090346 0.176374 0.241429 0.478637 0.052445
3 0.428487 0.176745 0.872160 0.572617 0.800724 0.096999 0.164391 0.076367 0.743757 0.224184
4 0.499604 0.384929 0.603271 0.950407 0.972324 0.662994 0.276461 0.207285 0.834498 0.918623
5 0.807182 0.345502 0.569022 0.191493 0.838638 0.142537 0.043660 0.797646 0.641671 0.661995
6 0.224364 0.117547 0.253472 0.800650 0.791210 0.662992 0.933724 0.982474 0.090368 0.848594
7 0.734468 0.164604 0.298378 0.037531 0.724353 0.976387 0.468621 0.428513 0.197949 0.995767
8 0.063096 0.463065 0.741885 0.302953 0.132439 0.706685 0.922946 0.336356 0.536714 0.288952
9 0.230219 0.353117 0.108670 0.385579 0.221161 0.118600 0.242965 0.544143 0.578594 0.983323

Excel文件

制作后缀为xlsx的Execl文件需要用到openpyxl库,如果后面的代码引发报错,可以通过jupyternotebook的单元格上运行以下pip命令进行安装

!pip install openpyxl -i 

回到正题,输出为excel文件也是用同样的方法

df.to_excel(r'./output/foo.xlsx', sheet_name='Sheet1', index=False)

检查文件夹,然后回来读取它

pd.read_excel(r'./output/foo.xlsx', 'Sheet1', index_col=None, na_values=['NA'])
col0 col1 col2 col3 col4 col5 col6 col7 col8 col9
0 0.188838 0.242863 0.009761 0.263796 0.819400 0.219437 0.376219 0.109041 0.483579 0.137196
1 0.537111 0.412955 0.845320 0.900356 0.500164 0.136346 0.055736 0.342375 0.780777 0.797048
2 0.485815 0.638531 0.050680 0.632832 0.489002 0.090346 0.176374 0.241429 0.478637 0.052445
3 0.428487 0.176745 0.872160 0.572617 0.800724 0.096999 0.164391 0.076367 0.743757 0.224184
4 0.499604 0.384929 0.603271 0.950407 0.972324 0.662994 0.276461 0.207285 0.834498 0.918623
5 0.807182 0.345502 0.569022 0.191493 0.838638 0.142537 0.043660 0.797646 0.641671 0.661995
6 0.224364 0.117547 0.253472 0.800650 0.791210 0.662992 0.933724 0.982474 0.090368 0.848594
7 0.734468 0.164604 0.298378 0.037531 0.724353 0.976387 0.468621 0.428513 0.197949 0.995767
8 0.063096 0.463065 0.741885 0.302953 0.132439 0.706685 0.922946 0.336356 0.536714 0.288952
9 0.230219 0.353117 0.108670 0.385579 0.221161 0.118600 0.242965 0.544143 0.578594 0.983323

HDF格式

HDF格式是层次数据格式,能够存储和组织大量数据。对于我们要保存的数据表还需要给它贴上一个标签

df.to_hdf(r'./output/foo.h5', 'df')

代码同样直观,但如果返回报错缺少pytables库的话这里有个小坑,用pip安装的包名是tables

!pip install tables -i 

成功保存后回头读取文件

pd.read_hdf(r'./output/foo.h5', 'df').head()
col0 col1 col2 col3 col4 col5 col6 col7 col8 col9
0 0.188838 0.242863 0.009761 0.263796 0.819400 0.219437 0.376219 0.109041 0.483579 0.137196
1 0.537111 0.412955 0.845320 0.900356 0.500164 0.136346 0.055736 0.342375 0.780777 0.797048
2 0.485815 0.638531 0.050680 0.632832 0.489002 0.090346 0.176374 0.241429 0.478637 0.052445
3 0.428487 0.176745 0.872160 0.572617 0.800724 0.096999 0.164391 0.076367 0.743757 0.224184
4 0.499604 0.384929 0.603271 0.950407 0.972324 0.662994 0.276461 0.207285 0.834498 0.918623

MySQL

当Python和MySQL联动的时候事情变得有意思了,首先确保自己的电脑上安装好MySQL并且登录运行创建一个名为test的数据库,然后准备两个包sqlalchemy和pymysql,可以pip安装。然后注意以下代码

from sqlalchemy import create_engine
import pymysql
 
engine = create_engine('mysql+pymysql://user:password@localhost:3306/test?charset=utf8')
df.to_sql('pyfoo', engine, schema='test', if_exists='replace', index=False)
  • 代码解读tips:首先是字符串"mysql+pymysql",你能在网上找到的版本通常是"mysql+mysqldb",这会触发pandas使用mysqldb工具,那是Python2.0时代的产物现在已经变成一个坑了。其次用MySQL的用户名替换"user"字符,密码替换"password"字符。

成功运行后是可以在MySQL的test数据库中找到这个名为pyfoo的表格,然后当然是读取它

sql = "select * from pyfoo;"
pd.read_sql(sql, engine)
  • 代码解读tips:用SQL语法定义一个字符串,给pandas在调用MySQL数据库时使用。
col0 col1 col2 col3 col4 col5 col6 col7 col8 col9
0 0.188838 0.242863 0.009761 0.263796 0.819400 0.219437 0.376219 0.109041 0.483579 0.137196
1 0.537111 0.412955 0.845320 0.900356 0.500164 0.136346 0.055736 0.342375 0.780777 0.797048
2 0.485815 0.638531 0.050680 0.632832 0.489002 0.090346 0.176374 0.241429 0.478637 0.052445
3 0.428487 0.176745 0.872160 0.572617 0.800724 0.096999 0.164391 0.076367 0.743757 0.224184
4 0.499604 0.384929 0.603271 0.950407 0.972324 0.662994 0.276461 0.207285 0.834498 0.918623
5 0.807182 0.345502 0.569022 0.191493 0.838638 0.142537 0.043660 0.797646 0.641671 0.661995
6 0.224364 0.117547 0.253472 0.800650 0.791210 0.662992 0.933724 0.982474 0.090368 0.848594
7 0.734468 0.164604 0.298378 0.037531 0.724353 0.976387 0.468621 0.428513 0.197949 0.995767
8 0.063096 0.463065 0.741885 0.302953 0.132439 0.706685 0.922946 0.336356 0.536714 0.288952
9 0.230219 0.353117 0.108670 0.385579 0.221161 0.118600 0.242965 0.544143 0.578594 0.983323

最后数据成功被读取出来了。在Python里使用SQL是有点奇妙的事情,如果感兴趣可以进一步去了解pymysql工具包。

小结

本次文章简单介绍了滑动窗口方法和pandas的文件读写IO。滑动窗口方法不仅可以用在时间索引Series上,也可以用在一般的Series上,虽然常见的用法都是基于时间序列数据的,但如果一般数据具备某些顺序特征也是可以使用的。

其次浅尝了一下pandas的文件读写,文件读写是为数据分析工作建立checkpoint的存在,其重要性可见一斑,今天介绍了4种常见文件格式的读写方法。最简单直观的就是csv格式,最有趣味的就是与MySQL的交互。好了本期文章到这里就结束了,感谢阅读。

本文标签: 滑动窗口 文件 代码解读