本文主要关注如何将各种Python对象储存为本地文件,并反之从本地文件加载Python对象。
(注意:一般情况下Python读写的工具都需要统一,如果可以跨工具使用的话,我会在对应内容的位置说明)
数据库就不算在内了,Python与数据库的交互我写了别的博文。
对XML对象的处理我单拎出来写了一篇博文:XML文件格式的简介及如何用Python3处理XML格式对象
文章目录
1. 使用Python3原生函数读写文件流
Python3使用原生函数open()
可以直接打开本地文件,返回值是文件流。
参数:
- 文件路径
- 打开模式,默认为
r
只读。其他可选项:w
写入,a
添加,rb
/wb
后面的b
指对二进制文件的处理1 encoding
:编码格式,常用选项为utf-8
或gbk
有两种常见写法,一种是将open()
作为命令,对返回的文件流进行处理,最后要记得close()
;一种是将open()
作为上下文管理器,如with open('file.txt') as f:
语句下包裹的代码运行之间自动打开文件流,运行完毕后自动关闭。
(如果对with语句之外的f进行I/O操作,将会报:ValueError: I/O operation on closed file.
这个bug)
对文件流的操作:
readlines()
对于文本文件,就是返回全部内容,列表格式,每行文字是一个元素read()
对于文本文件,就是返回全部内容,字符串格式write(str)
写入一个字符串对象writelines(obj)
写入一个可迭代对象的所有元素,obj
需要元素是字符串。注意:1. 不会自动换行。2. 集合对象也可以写入,但顺序随机;以字符串为键的字典对象也可以写入,但将只写入键值,具体的顺序我不确定。flush()
2 刷新内部缓冲(意思就是更新代码中各种写入操作)(在文件关闭时也会自动刷新一次)close()
关闭文件流(如果使用with open()
就不用显式关闭文件流)
2. JSON
Python 3内置json包
加载本地文件到内存中:json.load(文件流)
将Python对象储存到本地:json.dump(Python对象,文件流)
(文件流是通过open()
函数打开的)
将字符串对象转换为dict对象:json.loads(str)
将dict对象转换为字符串:json.dumps(obj)
dump()
和dumps()
的共有入参:
ensure_ascii
:默认置True, 这会导致转换得到的字符串无法用肉眼直接阅读。所以一般都会显式置False
使用JSON来储存数据的优势在于跨平台、跨语言。
在这里额外提供一些别的JSON工具包:
- json格式化(就算是不严格的JSON也可以格式化,比原始文本易读多了):https://www.bejson.com/
3. 使用pickle包
pickle包官方文档:https://docs.python.org/3/library/pickle.html
将Python对象储存为本地文件:
import pickle
data = [1, 2, 3, {'k': 'A1', '全文': '内容1'}] # 你的数据
with open('data.pkl', 'wb') as file:
pickle.dump(data, file)
加载本地文件到内存中:
import pickle
with open('data.pkl', 'rb') as file:
loaded_data = pickle.load(file)
print(loaded_data) # 输出: [1, 2, 3, {'k': 'A1', '全文': '内容1'}]
4. 处理CSV:csv包
csv包官方文档:csv — CSV File Reading and Writing — Python 3.11.0 documentation
从CSV文件中读数据:
import csv
with open(CSV文件名,newline='') as csvfile:
spamwreader=csv.reader(csvfile)
for row in spamreader:
#一行数据,列表对象,每个元素是该行的一个cell
将数据写入到CSV文件中:
import csv
with open(CSV文件名,'w',newline='') as csvfile:
spamwriter=csv.writer(csvfile)
spamwriter.writerow(一行列表对象(每个元素是该行的一个cell))
5. 处理Excel
1. xlsx: openpyxl包
openpyxl包官方中文文档:openpyxl - 读/写 Excel 2010 xlsx/xlsm 文件的 Python 库 — openpyxl 3.0.7 文档
安装openpyxl:pip install openpyxl
- 创建Workbook对象(相当于一个Excel文件)
- 新建一个(会默认创建一个sheet):
from openpyxl import Workbook wb=Workbook()
- 打开Excel文件:
from openpyxl import load_workbook wb2 = load_workbook('test.xlsx')
- 获取第一个sheet:
ws = wb.active
- 创建sheet:
ws=wb.create_sheet(sheet_name)
(返回sheet) - 通过sheet_name获取sheet:
ws=wb[sheet_name]
- 打印所有的sheet_name:
wb.sheetnames
(返回一个列表对象) - 提取某一元素(如果没有元素将自动创建空值)
从1开始ws.cell(row=line_index,column=column_index,value=jiancheng)
:定义value会自动赋值ws['A1']
:直接用单元格提取,可以直接赋值
ws.iter_rows(min_row=None, max_row=None, min_col=None, max_col=None, values_only=False)
:默认从A1开始
如果置value_only=True
,返回值是一个元素的迭代器- 将对象插入Excel:
- 将list插入Excel:
ws.append(list_object)
- 将dict插入Excel:
ws.append(list(dict_object.values()))
- 将list插入Excel:
- 将Workbook对象储存到Excel文件中(警告:这个操作将会无警告直接覆盖已有文件):
wb.save('an_excel.xlsx')
- 其他注意事项
- 使用openpyxl包在Linux上编程时,发现sheet name只是不允许添加
/
;但把excel文件下载到本地后会发现/
也不允许添加,office会自动把非法文字给删掉。所以建议在编程的时候就不要创建这种内容 - 如果试图用openpyxl包调用.xls文件,会得到如下报错信息:
InvalidFileException: openpyxl does not support the old .xls file format, please use xlrd to read this file, or convert it to the more recent .xlsx file format.
- 使用openpyxl包在Linux上编程时,发现sheet name只是不允许添加
openpyxl的更多进阶用法可以参考我写的其它博文:
- 单元格填色:styles.PatternFill
Excel如何给单元格填色,以及如何用Python 3实现单元格填色 - 合并单元格:
ws.merge_cells("A4:A5")
- 行分级:
ws.row_dimensions.group(8, 96, outline_level=1)
折叠分级按钮:ws.sheet_properties.outlinePr.summaryBelow = False
Excel如何实现行分级,以及如何用Python 3实现Excel行分级
2. xls:xlrd包
xlrd — xlrd 2.0.1 documentation
安装:pip install xlrd
使用示例:
import xlrd
book = xlrd.open_workbook("myfile.xls")
print("The number of worksheets is {0}".format(book.nsheets))
print("Worksheet name(s): {0}".format(book.sheet_names()))
sh = book.sheet_by_index(0)
print("{0} {1} {2}".format(sh.name, sh.nrows, sh.ncols))
print("Cell D30 is {0}".format(sh.cell_value(rowx=29, colx=3)))
for rx in range(sh.nrows): #按行循环
print(sh.row(rx)) #一个列表,每个元素是一格,一个xlrd.sheet.Cell
print(sh.row(rx)[0].value) #第一格的值
6. word文件:python-docx库
可以参考我撰写的博文:深入解析Python-docx库:轻松玩转Word文档自动化
7. 使用numpy包
1 一次性序列化多个对象
习惯以.npz
后缀存储
官方文档:https://numpy.org/devdocs/reference/generated/numpy.savez.html
https://numpy.org/devdocs/reference/generated/numpy.savez_compressed.html
8. 使用scipy包
1 scipy.sparse
习惯以.npz
后缀存储
储存对象:save_npz()
(官方文档:https://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.save_npz.html)
import scipy.sparse
sparse_matrix = scipy.sparse.csc_matrix(np.array([[0, 0, 3], [4, 0, 0]]))
scipy.sparse.save_npz('/tmp/sparse_matrix.npz', sparse_matrix)
加载本地对象:load_npz()
(官方文档:https://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.load_npz.html)
import scipy.sparse
sparse_matrix = scipy.sparse.load_npz('/tmp/sparse_matrix.npz')
9. 使用pandas包
1 CSV/Excel文件
10. 使用sklearn包
11. 使用PyTorch包
习惯以.pt
或.pth
后缀存储
PyTorch储存与加载模型的官方教程:Saving and Loading Models — PyTorch Tutorials 1.12.1+cu102 documentation
其他参考资料:python - How do I save a trained model in PyTorch? - Stack Overflow
将对象储存到磁盘:torch.save(obj,path)
将磁盘对象加载到内存:torch.load(path)
(path可以是路径字符串或文件流)
load()
入参:
map_location
:可以是函数、torch.device、字符串或字典,指定对象存储的设备位置。
获取模型参数(返回state_dict,匹配模型层到参数张量的字典文件,只包括可学习的那些。优化器对象也有这个):model.state_dict()
optimizer.state_dict()
将模型参数加载回模型:model.load(state_dict)
所以直接储存模型参数就是:torch.save(model.state_dict(), path)
直接加载模型参数就是:model.load_state_dict(torch.load(path))
需要注意的一个情况是:如果在每个epoch后,都根据当前指标,保存最好指标下的epoch的checkpoint,因为state_dict
是mutable对象OrderedDict
,所以直接引用(best_state = model.state_dict()
)的话会跟着模型的当前指标变化,因此需要深拷贝(best_state = copy.deepcopy(model.state_dict())
)3
12. 使用transformers包
13. 处理PDF
我现在依然不会用Python直接从PDF中提取格式。GPT-4说它也没辙:
(2023.6.21更新:看了一下,好像PyMuPDF可以,我还没试)
1 PyPDF2:逐页提取文字
请参考我之前撰写的博文:PyPDF2:使用Python操作PDF文件
2 tabula-py:提取表格
表格之外的内容全都无法提取(嗯所以我个人的解决方案是结合别的处理PDF的包一起使用)
安装方式:pip install tabula-py
注意:1. 如果想要使用这个包的话,需要安装Java 2. 这个包无法完全提取文档中的表格,有时会遗漏,有条件的话还是需要自己检查一遍的
import tabula
# 读取PDF文件
file = "中国计算机学会推荐国际学术会议和期刊目录-2022(拟定).pdf"
# 使用tabula读取PDF中的表格
tables = tabula.read_pdf(file, pages = "all", multiple_tables = True) #pages可以是int,int列表,或者'all'
# `tables`现在是一个包含所有表格的列表,每个表格都是一个pandas DataFrame
# 您可以通过索引来访问每个表格,例如:
first_table = tables[20]
# 打印第19个表格的内容
print(tables[20])
输出:
序号 会议简称 会议全称 出版社 网址
0 1 CF ACM International Conference on Computing Fron... ACM http://dblp.uni-trier.de/db/conf/cf
1 2 SYSTOR ACM International Systems and Storage Conference ACM http://dblp.uni-trier.de/db/conf/systor/index....
2 3 NOCS ACM/IEEE International Symposium on Networks-o... ACM/IEEE http://dblp.uni-trier.de/db/conf/nocs
3 4 ASAP Application-Specific Systems, Architectures, a... IEEE http://dblp.uni-trier.de/db/conf/asap
4 5 ASP-DAC Asia and South Pacific Design Automation Confe... ACM/IEEE http://dblp.uni-trier.de/db/conf/aspdac
5 6 ETS European Test Symposium IEEE http://dblp.uni-trier.de/db/conf/ets/
6 7 FPL Field Programmable Logic and Applications IEEE http://dblp.uni-trier.de/db/conf/fpl/
7 8 FCCM Field-Programmable Custom Computing Machines IEEE http://dblp.uni-trier.de/db/conf/fccm/
8 9 GLSVLSI Great Lakes Symposium on VLSI ACM/IEEE http://dblp.uni-trier.de/db/conf/glvlsi/
9 10 ATS IEEE Asian Test Symposium IEEE http://dblp.uni-trier.de/db/conf/ats/
10 11 HPCC IEEE International Conference on High Performa... IEEE http://dblp.uni-trier.de/db/conf/hpcc/
11 12 HiPC IEEE International Conference on High Performa... IEEE/ ACM http://dblp.uni-trier.de/db/conf/hipc/index.html
12 13 MASCOTS IEEE International Symposium on Modeling, Anal... IEEE http://dblp.uni-trier.de/db/conf/mascots/
3 PDFMiner
安装:pip install pdfminer
pdf2txt.py [-P password] [-o output] [-t text|html|xml|tag]
[-O output_dir] [-c encoding] [-s scale] [-R rotation]
[-Y normal|loose|exact] [-p pagenos] [-m maxpages]
[-S] [-C] [-n] [-A] [-V]
[-M char_margin] [-L line_margin] [-W word_margin]
[-F boxes_flow] [-d]
input.pdf
挺复杂的,总之我实验过txt和html两种文件,TXT就是纯纯转换为文本,我的意见是不如用PyPDF2,好歹能知道原本的页数;HTML看起来不能复原原文件中的背景色和字体,但是会以某种方式呈现出来。
但可能是因为我HTML没学好,反正我看起来觉得实在是太混乱了,我懒得研究了,我就放弃用这个包了。
4 pdfplumber
安装方式:pip install pdfplumber
提取表格(我的使用体验是不如tabula):
pdf = pdfplumber.open(pdf_file_path)
page = pdf.pages[page_index]
if not page.extract_table() is None: #说明提取出表格了,do something!
pass
5 PyMuPDF
官方文档:PyMuPDF 1.22.3 documentation
安装方式:pip install pymupdf
- 打开文件(是一个由
fitz.fitz.Page
对象组成的列表)import fitz doc = fitz.open(PDF路径)
- 从
fitz.fitz.Page
中提取文本:page.get_text()
返回字符串对象
入参:"blocks"
:返回元组列表,每个元组的格式类似这样:(107.57489776611328, 246.74249267578125, 505.5909118652344, 282.74249267578125, '专业学位硕士学位论文 \n', 0, 0)
:包含了block的位置信息“words”
:返回单词及对应的位置信息
- 从
fitz.fitz.Page
中提取图片:page.get_images()
返回图片。将图片保存为png格式:image_list = page.get_images() for image_index, img in enumerate(image_list, start=1): # enumerate the image list xref = img[0] # get the XREF of the image pix = fitz.Pixmap(doc, xref) # create a Pixmap if pix.n - pix.alpha > 3: # CMYK: convert to RGB first pix = fitz.Pixmap(fitz.csRGB, pix) pix.save("图"+str(image_number)+".png") # save the image as png pix = None image_number+=1
6 pdfreader
pypi官网:pdfreader · PyPI
14. 处理LaTeX
pylatex包
参考博文:
15. 本文撰写过程中使用的其他参考资料
- Python 处理Excel文件为了通用原则,建议用openpyxl库 - 简书
- Python xlrd read as string - Stack Overflow
- Python解析xml字符串_jack@london的博客-CSDN博客
- Python XML 解析 | 菜鸟教程
- XML 教程
- 【python小随笔】python解析xml格式字符串与xml文件
- python3基础:操作xml
- python无损提取pdf中的图片 - 知乎