详讲 Python 数据读写方式,面向Excel、Txt文档及M
1. 前言
Hello,大家好,我是小张~
在日常与 Python 打交道过程中,不可避免会涉及到数据读写业务,例如做爬虫时,需要将爬取的数据首先存储到本地然后再做下一步处理;做数据可视化分析时,需要将数据从硬盘中读入内存上,再进行后续的数据清洗、可视化、建模等步骤
对数据进行读写操作时,对于存储对象我们有多种选择,最方便的是本地文档类型:csv、txt 等,优点是方便简单、但弊端也很明显:文档型数据易丢失、损坏,删除不可恢复,且不方便多人间数据共享;
另一大类存储对象为数据库,目前比较流性的持久化数据库为 MongoDB 和Mysql ;对比文档存储,数据库最大的优势就是:数据不易丢失且易检索,面对庞大数据量仅几行 sql
语句即可实现 CRUD(增、读、改、删) 功能
在本期 Python 教程中,将汇总一下有关 Python 数据读写方式,涉及到的存储对象有四类:txt、csv、MongoDV以及MySQL
2. Python 文档读写
关于本地文档数据读写,本文列出两类常见文档类型: txt 及 csv ;测试数据来源于链家二手房房源,关于房源数据爬取详情参考旧闻 Python 采集了3000 条北京二手房数据,看看我都分析出来了啥?
image-202106171502282092.1 txt 读写
在本文介绍的几种数据存储对象中,txt 读写是最简单的一种,关于读写方式这里我就不作详细介绍了,不太了解的小伙伴可以参考下方测试代码:
# txt 数据源,需记得加上 encoding='utf-8' 参数,防止乱码
dataSource = open('data.txt',encoding='utf-8',mode='r')
# txt 数据读写操作
savePath = 'save.txt'
f = open(savePath,encoding='utf-8',mode='w+')# 读取
for lineData in dataSource.readlines():
dataList = lineData.replace('\n','').split(',')
print(dataList)
f.write('\t'.join(dataList) +'\n')
f.close()
txt 读写整个流程都是借助文件流方式完成的,需要注意的是在读写过程中若出现中文乱码情况,需要加上参数encoding = 'utf-8'
即可有效避免:
2.2 csv 读写
与 txt 相比 ,Python爱好者更偏爱把数据存入 csv 或 xlsx,后者相对更为规范,尤其是面向数值数据,对于编程基础并不好的同学,不需要 Python 借助 Excel 可以直接进行可视化分析;
csv 在 Python 中有多种读写方式,下面实例中我列出其中常见的两种,一种是基于 python-csv
、另一种是基于pandas
csv 数据读取
读取测试时,是从 csv 中读入数据
image-20210617155929618方法一,借助python-csv
读取
# 利用 python-csv 实现数据读取
csvPath = 'save.csv'
with open(csvPath, newline='',encoding='utf-8') as csvfile:
spamreader = csv.reader(csvfile, delimiter=',', quotechar='|')
for row in spamreader:
print(', '.join(row))
方法二,借助 pandas
读取
csvPath = 'save.csv'
df = pandas.read_csv(csvPath,header=0)
print(df)
csv 数据写入
方法一,借助 python-csv
# txt 数据源,需记得加上 encoding='utf-8' 参数,防止乱码
dataSource = open('data.txt',encoding='utf-8',mode='r')
# 利用 python-csv 实现 csv 文件写入
csvPath = 'save.csv'
with open(csvPath, 'w', newline='',encoding='utf-8') as csvfile:
spamwriter = csv.writer(csvfile, delimiter=' ',
quotechar='|', quoting=csv.QUOTE_MINIMAL)
for index, lineData in enumerate(dataSource.readlines()):
dataList = lineData.replace('\n', '').split(',')
spamwriter.writerow(dataList)
方法二,借助pandas
dataSource = open('data.txt',encoding='utf-8',mode='r')
# 利用 pandas 实现 csv 文件写入
csvPath = 'save.csv'
data = []
columnName = []
for index,lineData in enumerate(dataSource.readlines()):
if(index==0):# 第一行作为列名
columnName = lineData.replace('\n','').split(',')
continue
dataList = lineData.replace('\n','').split(',')
data.append(dataList)
df =pandas.DataFrame(data,columns =columnName)
# 防止乱码
df.to_csv(csvPath,encoding="utf_8_sig",index=False)
关于用 Python 操作 csv 文件,个人更喜欢用 pandas 来处理,在 pandas 中数据皆以 DataFrame
或 Series
类型展示,对于大部分数值计算或统计分析方法都有封装好的函数,直接调用即可,非常方便
关于 pandas 的基础使用,详情可参考旧文:
- Pandas 数据处理(一) —— 几个简单函数掌握!
- Pandas 数据处理(二) —— 条件筛选与排序!
- Pandas数据处理(三) — 分组聚类(groupby)
- Pandas数据处理|apply()函数的常规用法
- Pandas 基本使用— DataFrame.to_dict() 函数使用
3 Python 数据库读写
介绍完 Python 在本地文档中的读写方式,下面将介绍一下 Python 在数据库中的处理;这里我选择了 MongoDB 和 MySQL 两个比较流行的数据库;在正式介绍之前请确保大家的环境已经配好
3.1 MongoDB 数据读写
Mongodb 是一类面向文档型数据库,属于 NoSQL 阵营,也就是常说的非关系型数据库,
存储时将数据接受由 键值对 (key=> value) 组成,类似于 JSON 对象;也就是说 Python 与 Mongodb 数据交互时,需要以字典形式传递
那如何用Python来连接 MongoDB 呢?这个不需要我们担心,Python 最大的优势就可以依赖庞大的第三方库 ,借助 pymongo
可帮我们对 MongoDB 中的数据实现 CRUD 业务操作
MongoDB 连接初始化
本地端 MongoDB 下载完成之后,数据库默认端口为 127017
,主机地址为 loclhost
,在进行数据读写之前,需要对数据库完成初始化连接,代码如下
import pymongo
# 连接数据库,创建数据表
myclient = pymongo.MongoClient("mongodb://localhost:27017")
database = myclient["database"]# 连接接数据库
collection = database["table"]# collection 类似于Mysql中的 table
代码中 "database"
、"table"
分别表示数据库名、表名,在数据写入时若不存在对应数据库或数据表,MongoDB 会自动创建
MongoDB 数据写入
之前在介绍 MongoDB 时,提到它的数据结构由键值对组成,类似于 JSON 对象;因此在数据插入步骤中,需将数据转化为字典形式(列名作为 key,列值作为 value),数据样式如下:
image-20210618201508454数据写入 Python 代码实现
dataSource = open('data.txt',encoding='utf-8',mode='r')
readlines = dataSource.readlines()
keys_list = readlines[0].replace('\n', '').split(',')
for lineData in readlines[1:]:
dataList = lineData.replace('\n', '').split(',')
# 数据字典格式化
dataDict = dict(zip(keys_list, dataList))
if collection.find_one(dataDict):# 插入前判断数据表中是否存在该数据记录;
print("Insert done......")
else:# 不存在时插入
collection.insert_one(dataDict)
数据写入后效果如下,这里 GUI 工具用的是官方提供的 mongo compass
image-20210618201226498pymongo 数据插入可通过两种方式完成
-
insert_one()
每次插入一条数据; -
insert_many()
每次插入多条数据,插入多条数据需要以列表形式存储;
MongoDB 数据读取
MongoDB 数据读取,可以理解为无条件查询,通过 find()
返回 一个 Cursor
对象;Cursor 中文意思就是游标,与迭代器特性相似,可通过迭代方式依次返回数据库数据
数据读取方式如下:
myclient = pymongo.MongoClient("mongodb://localhost:27017")
database = myclient["database"]
collection = database["table"]
for post_data in collection.find():
print(post_data)
image-20210618203319021
除了无条件查询外,可以加入一些筛选条件,如下:
- 查询时,只返回前10条数据
for post_data in collection.find()[:10]:
print(post_data)
- 查询时,需以某个字段值以逆序方式返回,例如
_id
字段
for post_data in collection.find().sort('_id',pymongo.ASCENDING):
print(post_data)
image-20210618204859665
- 只返回
community
为西宏苑
的数据
for post_data in collection.find({"community":"西宏苑"}):
print(post_data)
image-20210618205151431
关于如何用 pymongo 操作 MongoDB, 还有许多实用方法,这里我只介绍了其中一小部分,详情可参考 pymongo 官方文档:
https://pymongo.readthedocs.io/en/stable/api/pymongo/collection.html
3.2 MySQL 读写
MySQL属于典型的关系型数据库,数据表间可以通过外键衔接,这样当一个字段在某个表中得到更新,其它相关联数据表中也会进行自动更新,数据增删改查业务逻辑主要通过 SQL 语句完成,
python 操控 MySQL 目前有两类库可以使用,MySQLdb 和 pymysql ,两个库操作mysql 方法相似,核心功能都是依赖于 sql 语句,可以认为提供了一个Python 与 MySQL 连接的接口,
在本文中选择 pymysql 作 为测试库,用 pymysql 进行读写之前,建议通过命令行测试一下本机上 MySQL 数据库是否可用,测试方法如下:
image-20210614202619879MySQL 连接初始化
pymysql 连接 MySQL 时需要配置 ip、端口、用户名、密码、及数据库名称(与 MongoDB 不同的是,MySQL 数据库需要提前创建好)
import pymysql
db_conn = pymysql.connect(host= '127.0.0.1', port= 3306, user= 'root', password= '123456', db= 'db_example')
MySQL数据插入
向 MySQL 中插入数据时,可以新建一个表,也可以基于原有数据库中的表进行插入,在下面测试代码中我采用的是前者
# 创建 table data_table
sql1 = " drop table if exists %s;"
sql2 ='''CREATE TABLE %s (
title varchar(1000),
community varchar(1000),
citydirct varchar(1000),
houseinfo varchar(1000),
dateinfo varchar(1000),
taglist varchar(1000),
totalprice varchar(1000),
unitprice varchar(1000)
)
'''
try:
with db_conn.cursor() as cursor:
cursor.execute(sql1,"data_table")
cursor.execute(sql2,"data_table")
db_conn.commit()
except Exception as e:
db_conn.rollback()
MySQL 数据插入代码
for lineData in dataSource.readlines()[1:]:
dataList = lineData.replace('\n', '').split(',')
# 拼接 sql 插入语句
insert_sql = 'INSERT data_table (title,community,citydirct,houseinfo,dateinfo,taglist,totalprice,unitprice) VALUES ' + \
'("' + '","'.join(dataList) + '")'
print(insert_sql)
# 执行sql 语句
with db_conn.cursor() as cursor:
cursor.execute(insert_sql)
# 关闭数据库
db_conn.close()
数据插入效果如下,下面是用 Navicat作为 mysql 的UI界面:
image-20210619185444542从上面代码块可以了解到,在pymysql 连接 MySQL 并将数据插入步骤中,业务功能主要是依赖于 sql 语句,也就是说想要用 python 操作 MySQL 的话,需要提前掌握一下 SQL 语句
INSERT data_table (title,community,citydirct,houseinfo,dateinfo,taglist,totalprice,unitprice) VALUES ' + \
'("' + '","'.join(dataList) + '")
pymysql 操作 MySQL 需要注意的是,每执行完 一条或多条 sql 语句时,需要 commit()
一下,否则执行无效
cursor.execute(sql2,"data_table")
db_conn.commit()
MySQL数据查询
通过 SELECT * FROM data_table
语句即可查询到数据表 data_table 中的所有数据:
import pymysql
db_conn = pymysql.connect(host= 'localhost',
port=3308,
user= 'root',
password= '123456',
db= 'db_example',
charset='utf8mb4')
findSql = 'SELECT * FROM data_table'
try:
with db_conn.cursor() as cursor:
cursor.execute(findSql)
db_conn.commit()
results = cursor.fetchall()
for itemData in results:
print(itemData)
except Exception as e:
db_conn.rollback()
image-20210619190820702
除了无条件查询外,当然也可以通过SELECT * FROM data_table where ....
语句来实现条件查询, ...
代表需要添加的条件语句
除了基本读写之外,借助 sql 语句也可以做一些更新、删除等业务功能;麻烦一点的就是,用 Python 拼接 sql 语句时会容易出现语法错误,这一点远不如 Java,
在 Java 中有封装好的 jar 包,对一些常见的增删改查业务只需要传入参数,不需要关心 sql 语句是否合法,非常方便! 与 Java 相比,Python 与 MySQL 交互操作还有很大的改进空间 ~
小结
本文分别介绍了Python 面向四类存储对象的读写方式,分为文档和数据库两大类,从 txt 到 csv,从MongoDB 到 MySQL,涵盖日常生活中的大部分业务场景;对于大部分学习Python的小伙伴,为了便捷性,用 Python 处理数据时都会首选 txt、csv 等文档作为存储对象;
但是一旦数据量变得庞大,或者存储数据的文档很多时,文档对象存储的弊端就会显露出来:文档数据易被误删、数据间关系容易混淆,文档乱放等问题;此时数据库的优势就能显露出来:
1,庞大的数据存储量,在MySQL3.22 版本中 单表最大存储空间为 4GB ,一个数据库可以创建多个数据表,MySQL 也可以创建多个数据库,如下图所示
image-202106200118403592,数据表间关系清晰,容易快速检索;一个数据库就可以把多个数据表汇聚到一处,方便查找;伴随数据量增加,还可以根据属性、使用场景将数据划分为多个数据库进行存储;
image-202106191956403533,数据库中数据如果误删的话还可通过技术手段恢复,因此了解数据库数据基本操作方式还是很有必要的!
好了,关于Python 数据存储就介绍到这里了,如果内容对你有帮助的话不妨点个赞来鼓励一下我~
最后感谢大家的阅读,我们下期见 !