convert_types.py 脚本中保存了一个列表,列表中存放的是pv行为,如:[‘离线动作-列表页-到这里去 1’,’离线动作-图区-搜周边 2’,’离线动作-图区-到这里去 1’…]
今天想要将 convert_types.py 里的pv行为全部都放在excel表里,行为名称和行为编号分开存放,于是使用pandas 中的dataframe结构存放数据,再将dataframe的数据写入excel文件中,代码写好后运行程序却报了以下错误:
1 | UnicodeDecodeError: 'ascii' codec can't decode byte 0xe5 in position 7: ordinal not in range(128) |
查阅资料后解决了以下两个问题
dataframe 如何写入数据到excel 文件中
单个dataframe 写入数据到excel 文件中
将整个dataframe 写入excel 文件,直接调用dataframe的to_excel()函数即可
1 | # result 为结果列表,将列表转化为DataFrame类型数据 |
to_excel()参数解释:
1 | DataFrame.to_excel(excel_writer, sheet_name='Sheet1', na_rep='', |
excel_writer : 字符串或ExcelWriter 对象——文件路径或现有的ExcelWriter
sheet_name :字符串,默认“Sheet1”——将包含DataFrame的表的名称。
na_rep : 字符串,默认‘ ’——缺失数据表示方式
float_format : 字符串,默认None——格式化浮点数的字符串
columns : 序列,可选——要编写的列
header : 布尔或字符串列表,默认为Ture。——写出列名。如果给定字符串列表,则假定它是列名称的别名。
index :布尔,默认的Ture——写行名(索引)
index_label : 字符串或序列,默认为None。——如果需要,可以使用索引列的列标签。如果没有给出,标题和索引为true,则使用索引名称。如果数据文件使用多索引,则需使用序列。
startrow :——左上角的单元格行来转储数据框
startcol :——左上角的单元格列转储数据帧
engine : 字符串,默认没有——使用写引擎-也可以通过选项io.excel.xlsx.writer,io.excel.xls.writer和io.excel.xlsm.writer进行设置。
merge_cells : 布尔,默认为Ture——编码生成的excel文件。只有xlwt需要,其他编写者本地支持unicode。
inf_rep : 字符串,默认“正”——无穷大的表示(在Excel中不存在无穷大的本地表示)
freeze_panes : 整数的元组(长度2),默认为None。——指定要冻结的基于1的最底部行和最右边的列
多个DataFrame 分为多个表写入同一个excel 文件中
需要通过ExcelWriter()方法打开一个已经存在的excel表格作为writer,然后通过to_excel()方法将需要保存的数据逐个写入excel,最后关闭writer
1 | write = pd.ExcelWriter('filePath') |
结果为excel 表中有表名为’data1’和’data2’的两张小表
多个DataFrame 写入一个excel 文件同一个表中
数据定义与上一个相同,只不过需要更改to_excel()函数中的参数而已
1 | write = pd.ExcelWriter('filePath') |
df数据从表格的第十行开始插入
df1数据从表格的第三十行和第十列开始插入
注意第二个数据插入的地方不能有其他数据,否则数据会覆盖。
sys.setdefaultencoding(‘utf-8’)的使用
Python 里面的编码和解码也就是 unicode 和 str 这两种形式的相互转化。编码是 unicode -> str,相反的,解码就是 str -> unicode。剩下的问题就是确定何时需要进行编码或者解码了。
关于文件开头的”编码指示”,也就是 # -*- coding: -*- 这个语句。Python 默认脚本文件都是 UTF-8 编码的,当文件中有非 UTF-8 编码范围内的字符的时候就要使用”编码指示”来修正。关于 sys.defaultencoding,这个在解码没有明确指明解码方式的时候使用。
1 | #! /usr/bin/env python |
这句代码将 s 重新编码为 gb18030 的格式,即进行 unicode -> str 的转换。因为 s 本身就是 str 类型的,因此 Python 会自动的先将 s 解码为 unicode ,然后再编码成 gb18030。因为解码是python自动进行的,我们没有指明解码方式,python 就会使用 sys.defaultencoding 指明的方式来解码。很多情况下 sys.defaultencoding 是
ANSCII,如果 s 不是这个类型就会出错。拿上面的情况来说,sys.defaultencoding 是 anscii,而 s 的编码方式和文件的编码方式一致,是 utf8 的,所以出错了:
1 | UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128) |
出现这种情况时有两种方法来解决:
明确的指示出 s 的编码方式
1 | #! /usr/bin/env python |
先用 utf-8 解码,再用 gb18030 编码,就不会出错了
更改 sys.defaultencoding 为文件的编码方式
1 | #! /usr/bin/env python |
这是个固定用法,Python2.5 初始化后删除了 sys.setdefaultencoding 方法,所以需要重新载入 sys
dataframe.read_excel()
顺带说一下使用dataframe读取excel文件的方法
1 | read_excel(io, sheetname=0, header=0, skiprows=None, skip_footer=0, index_col=None,names=None, parse_cols=None, parse_dates=False,date_parser=None,na_values=None,thousands=None, convert_float=True, has_index_names=None, converters=None,dtype=None, true_values=None, false_values=None, engine=None, squeeze=False, **kwds) |
常用参数解析:
- io : string, path object ; excel 路径。
- sheetname : string, int, mixed list of strings/ints, or None, default 0 返回多表使用sheetname=[0,1],若sheetname=None是返回全表 注意:int/string 返回的是dataframe,而none和list返回的是dict of dataframe
- header : int, list of ints, default 0 指定列名行,默认0,即取第一行,数据为列名行以下的数据 若数据不含列名,则设定 header = None
- skiprows : list-like,Rows to skip at the beginning,省略指定行数的数据
- skip_footer : int,default 0, 省略从尾部数的int行数据
- index_col : int, list of ints, default None指定列为索引列,也可以使用u’strings’
- names : array-like, default None, 指定列的名字。
附上完整代码
1 | #! /usr/bin/env python |