?前言
xlsx 格式文档文件无法被EXCEL2003 及以下版本EXCEL 软件直接打开编辑,安装OFFICE2007 兼容包后可以打开查看。手动将XLSX 文件后缀修改为XLS 无法改变文档文件的本质属性,是不能被EXCEL2003 等低版本EXCEL 直接打开编辑的。用户可在EXCEL 软件成功打开EXCEL2007 专有XLSX 格式文档的前提下,采用另存为方式将其转换为EXCEL97—2003 格式文档的XLS 文件这样可与旧的版本兼容,但一些EXCEL2007 文档专有的特性格式可能丢失。Excel xls 和xlsx 的详细区别如下:
- 文件格式不同:
xls 是一个特有的二进制格式,其核心结构是复合文档类型的结构,而xlsx 的核心结构是XML 类型的结构,采用的是基于XML 的压缩方式,使其占用的空间更小。xlsx 中最后一个x 的意义就在于此。- 版本不同:
xls 是excel2003 及以前版本生成的文件格式,不管有没有宏程序的话都是xls 文件,而xlsx 是excel2007 及以后版本生成的文件格式,从2007 开始做了区分,XLSM 文件和XLSX 文件都是excel2007 及其以后的文件,但前者是含有宏启用,Excel 中默认情况下不自动启用宏,默认是XLSX 。VBA 中,如果不想保存代码,可以保存为xlsx ,即可自动删除其中VBA 代码,反之则保存为XLSM 文件。- 兼容性不同:
xlsx 格式是向下兼容的,可兼容xls 格式。07版的Office Excel ,能打开编辑07版(后缀.xlsx )的Excel 文件,也能打开编辑03版(后缀.xls )的Excel 文件,都不会出现乱码或者卡死的情况。03版的Office Excel ,就只能打开编辑03版(后缀.xls )的Excel 文件;如果打开编辑07版(后缀.xlsx )的Excel 文件,则可能出现乱码或者开始能操作到最后就卡死,以后一打开就卡死。- 默认保存方式上:
xls 是03版Microsoft Office Excel 工作表的格式,用03版Office,新建Excel 默认保存的Excel 文件格式的后缀是.xls ;xlsx 是07版Microsoft Office Excel 工作表的格式,用07版Office,新建Excel 默认保存的的Excel 文件格式后缀是.xlsx 。- 容量不同:
xls 只有65536行、256列;xlsx 可以有1048576行、16384列
?Python之读写文件
??CSV
(1)CSV库读取
import csv with open(r"D:Desktopdata.csv") as file: reader = csv.reader(file) print(reader) print("*"*20) # 用next()函数读取文件时:如果只执行一次默认读取第一行。 headers = next(reader) print(headers) print("*"*20) for row in reader: print(row) print(row[2]) # 输出结果 <_csv.reader object at 0x000001D6B95F1668> ******************** ['name', 'gender', 'age', 'hobby'] ******************** ['小红', '女', '20', '跑步'] 20 ['小汤', '男', '22', '篮球'] 22 ['小李', '男', '24', '足球'] 24
# 获取一行数据中的某一列数据 import csv from collections import namedtuple with open(r"D:Desktopdata.csv") as file: reader = csv.reader(file) print(reader) print("*"*20) headers = next(reader) # namedtuple(具名元组)返回一个具名元组子类 typename Row = namedtuple('Row', headers) print(headers) print("*"*20) for row in reader: # 列表或元组前面加星号作用是将列表解开成两个独立的参数; # 字典前面加两个星号,是将字典的值解开成独立的元素作为形参。 row = Row(*row) # 获取一行数据中的某一列数据。 print(row.name,row.age) # 输出结果 <_csv.reader object at 0x000001D6B95F1128> ******************** ['name', 'gender', 'age', 'hobby'] ******************** 小红 20 小汤 22 小李 24
简单使用
可以深入了解该函数的参数:
csv.DictReader() 之fieldnames 参数csv.DictReader() 之restkey 参数csv.DictReader() 之restval 参数
import csv with open(r"D:Desktopdata.csv") as file: ''' # 如果没有字段名,参数fieldnames reader = csv.DictReader(file,fieldnames = ['name','gender','age','hobby']) # next()方法用于移动指针 head_row = next(reader) ''' reader = csv.DictReader(file) print(reader) print("*"*20) for row in reader: # OrderedDict是一种长相类似于列表的数据类型,该列表中嵌套着元组; # 每个元组中的第一个元素为键,第二个元素为值(类似于字典) print(row) print(row["name"],row["hobby"]) # 输出结果 <csv.DictReader object at 0x000001D6B95F0388> ******************** OrderedDict([('name', '小红'), ('gender', '女'), ('age', '20'), ('hobby', '跑步')]) 小红 跑步 OrderedDict([('name', '小汤'), ('gender', '男'), ('age', '22'), ('hobby', '篮球')]) 小汤 篮球 OrderedDict([('name', '小李'), ('gender', '男'), ('age', '24'), ('hobby', '足球')]) 小李 足球
(2)CSV库写入
import csv # 1. 创建文件对象(指定文件名,模式,编码方式),指定下次写入在这次的下一行 # 注意引入newline="",不然加入的数据会空一行 with open(r"D:Desktopdata.csv", "a+", encoding="gbk", newline="") as f: # 2. 基于文件对象构建 csv写入对象 csv_writer = csv.writer(f) # 3. 构建列表头 # name = ['name','gender','age','hobby'] # csv_writer.writerow(name) # 4. 写入csv文件内容 z = [["小ai", "男", 21, "篮球"],["小张", "男", 25, "篮球"]] csv_writer.writerows(z) with open(r"D:Desktopdata.csv", "r+", encoding="gbk", newline="") as f: reader = csv.reader(f) headers = next(reader) for row in reader: print(row) # 输出结果 ['小红', '女', '20', '跑步'] ['小汤', '男', '22', '篮球'] ['小李', '男', '24', '足球'] ['小ai', '男', '21', '篮球'] ['小张', '男', '25', '篮球']
如果
csvfile 是文件对象,则打开它时应使用newline="" 。如果没有指定newline="" ,则嵌入引号中的换行符将无法正确解析,并且在写入时,使用换行的平台会有多余的
写入。由于
csv 模块会执行自己的(通用)换行符处理,因此指定newline="" 应该总是安全的。
open() 完成后必须调用close() 方法关闭文件,因为文件对象会占用操作系统资源,并且操作系统同一时间能打开的文件数量也是有限的。由于文件读写时有可能产生IOError ,一旦出错,后面的f.close() 就不会调用。with open() 则可以避免这样的情况。
模式 | 描述 |
---|---|
以文本格式打开文件(默认)。一般用于文本文件,如: |
|
以二进制格式打开文件。一般用于非文本文件,如:图片。 | |
以只读方式打开文件(默认模式)。文件的指针将会放在文件的开头,如果文件不存在会报错。 | |
以只写方式打开文件。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,则创建新文件。 | |
以追加方式打开文件,同样是只写,不允许进行读操作。如果文件已存在,文件指针将会放在文件的结尾,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 | |
打开一个文件用于读写。如果文件存在,则打开文件,将文件指针定位在文件头,新写入的内容在原有内容的前面;如果文件不存在会报错。 | |
打开一个文件用于读写。如果文件存在,则打开文件,清空原有内容,进入编辑模式;如果文件不存在,则创建一个新文件进行读写操作。 | |
以追加模式打开一个文件用于读写。如果文件存在,则打开文件,将文件指针定位在文件尾,新写入的内容在原有内容的后面;如果文件不存在,则创建一个新文件用于读写。 | |
以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。一般用于非文本文件如图片等。 | |
以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。 | |
以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 | |
以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。一般用于非文本文件如图片等。 | |
以二进制格式打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。 | |
以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。 |
csv 库常见的问题
csv.DictWriter() :该函数返回的结果遍历一次之后,再次遍历返回的结果是空列表。csv.reader() :返回的结果是结构体,需要for 循环才能调用,不能像list 那样直接选取特定单元格。- 通过列名来查找指定列的操作麻烦。
(3)pandas库读取
使用
pandas 读取csv 文件的优势:
- 方便,有专门支持读取
csv 文件的pd.read_csv() 函数;- 将
csv 转换成二维列表形式;- 支持通过列名查找特定列;
- 相比
csv 库,事半功倍。
pandas.read_csv(filepath_or_buffer, sep=, delimiter=None, header=‘infer’, names=None, index_col=None, usecols=None, squeeze=False, prefix=None, mangle_dupe_cols=True, dtype=None, engine=None, converters=None, true_values=None, false_values=None, skipinitialspace=False, skiprows=None, skipfooter=0, nrows=None, na_values=None, keep_default_na=True, na_filter=True, verbose=False, skip_blank_lines=True, parse_dates=False, infer_datetime_format=False, keep_date_col=False, date_parser=None, dayfirst=False, cache_dates=True, iterator=False, chunksize=None, compression=‘infer’, thousands=None, decimal=’.’, lineterminator=None, quotechar='"', quoting=0, doublequote=True, escapechar=None, comment=None, encoding=None, dialect=None, error_bad_lines=True, warn_bad_lines=True, delim_whitespace=False, low_memory=True, memory_map=False, float_precision=None, storage_options=None) # 常用参数详解 (1)filepath_or_buffer:必须有的参数,其它都是按需求选用的。文件所在处的路径。 (2)sep:指定分隔符,默认为逗号','。 (3)delimiter:str/default/None,定界符,备选分隔符(如果指定该参数,则sep参数失效) (4)header:int or list of ints, default ‘infer’,指定哪一行作为表头。默认设置为0(即第一行作为表头),如果没有表头的话,要修改参数,设置header=None。 (5)names:指定列的名称,用列表表示。一般我们没有表头,即header=None时,这个用来添加列名就很有用啦。 (6)index_col:指定哪一列数据作为行索引,可以是一列,也可以多列。多列的话,会看到一个分层索引。 (7)squeeze:布尔值,默认为False。如果解析的数据仅包含一列,则返回一个Series。 (8)prefix:给列名添加前缀。如prefix="x",会出来"x1"、"x2"、"x3"。 (9)nrows:int, default None。需要读取的行数(从文件头开始算起)。 (10)encoding:编码方式。 (11)skiprows:list-like or integer, default None。在文件开始处要跳过的行号(索引为0)或要跳过的行数(整数)。 ......
import pandas as pd df = pd.read_csv(r"D:Desktopdata.csv",encoding="gbk") print(df) print("*"*20) print(df.index.values) print(df.columns.values) print(df.values) # 通过位置选取 print("="*20) print(df.iloc[:,0:3].values) print(type(df.iloc[:,0:3].values)) print(df.iloc[:,0:3].values.tolist()) print(type(df.iloc[:,0:3].values.tolist())) # 通过标签选取 print("-"*20) print(df.loc[[0,3],["name","hobby"]].values) # 输出结果 name gender age hobby 0 小红 女 20 跑步 1 小汤 男 22 篮球 2 小李 男 24 足球 3 小ai 男 21 篮球 4 小张 男 25 篮球 ******************** [0 1 2 3 4] ['name' 'gender' 'age' 'hobby'] [['小红' '女' 20 '跑步'] ['小汤' '男' 22 '篮球'] ['小李' '男' 24 '足球'] ['小ai' '男' 21 '篮球'] ['小张' '男' 25 '篮球']] ==================== [['小红' '女' 20] ['小汤' '男' 22] ['小李' '男' 24] ['小ai' '男' 21] ['小张' '男' 25]] <class 'numpy.ndarray'> [['小红', '女', 20], ['小汤', '男', 22], ['小李', '男', 24], ['小ai', '男', 21], ['小张', '男', 25]] <class 'list'> -------------------- [['小红' '跑步'] ['小ai' '篮球']]
(4)pandas库写入
DataFrame.to_csv(path_or_buf=None, sep=',', na_rep='', float_format=None, columns=None, header=True, index=True, index_label=None, mode='w', encoding=None, compression='infer', quoting=None, quotechar='"', lineterminator=None, chunksize=None, date_format=None, doublequote=True, escapechar=None, decimal='.', errors='strict', storage_options=None) # 常用参数详解 (1)path_or_buf:字符串,放文件名、相对路径、文件流等。 (2)sep:字符串,分隔符,跟read_csv()的一个意思。 (3)na_rep:字符串,将NaN转换为特定值。 (4)columns:列表,指定哪些列写进去。 (5)header:默认header=0,如果没有表头,设置header=None,表示我没有表头呀! (6)index:关于索引的,默认True,写入索引 (7)mode:{‘w’, ‘x’, ‘a’}, default ‘w’,写入方式。 (8)encoding:编码方式。 ......
import pandas as pd name = ["小小","小耿"] gender = ["男","男"] age = [20,25] hobby = ["跳绳","羽毛球"] dict_data = {"name":name,"gender":gender,"age":age,"hobby":hobby} df1 = pd.DataFrame(dict_data) # mode = "a"为追加数据,index为每行的索引序号,header为标题 df1.to_csv("D:Desktopdata.csv",mode="a",index=False,header=False,encoding="gbk") df2 = pd.read_csv(r"D:Desktopdata.csv",encoding="gbk") print(df2) # 输出结果 name gender age hobby 0 小红 女 20 跑步 1 小汤 男 22 篮球 2 小李 男 24 足球 3 小ai 男 21 篮球 4 小张 男 25 篮球 5 小小 男 20 跳绳 6 小耿 男 25 羽毛球
??Excel
xlrd 库:从excel 中读取数据,支持xls 、xlsx ;xlwt 库:对excel 进行修改操作,不支持对xlsx 格式的修改;xlutils 库:在xlw 和xlrd 中,对一个已存在的文件进行修改;openpyxl 库:主要针对xlsx 格式的excel 进行读取和编辑;xlwings 库:对xlsx 、xls 、xlsm 格式文件进行读写、格式修改等操作;xlsxwriter 库:用来生成excel 表格,插入数据、插入图标等表格操作,不支持读取;Microsoft Excel API :需安装pywin32 ,直接与Excel 进程通信,可以做任何在Excel 里可以做的事情,但比较慢。
(1)读取Excel文件
pd.read_excel(io, sheet_name=0, header=0, names=None, index_col=None, usecols=None, squeeze=False,dtype=None, engine=None, converters=None, true_values=None, false_values=None, skiprows=None, nrows=None, na_values=None, parse_dates=False, date_parser=None, thousands=None, comment=None, skipfooter=0, convert_float=True, **kwds) # 常见参数详解 (1)io:文件的路径。 (2)sheet_name:读取的工作表的名称;可以是整型数字、列表名,如果读取多个sheet,也可以是它们组成的列表;以0为起始点。 (3)header:指定哪几行做列名;默认header为0,如果设置为[0,1],则表示将前两行作为多重索引。 (4)names:自定义列名;长度必须和excel的列大小相同;如果缺少列名,使用names指定列名字,会替代原来的列表头。 (5)index_col:用作索引的列;可以是某列的名字,也可以是整型数字或列表。 (6)usecols:指定读取的列;列从0开始,可以是列表,也可以使用Excel的列名,如'A','B'等字母。 (7)squeeze:一列数据时,返回Series还是DataFrame。仅当Excel只有一列的时候起作用,squeeze为True时,返回Series,反之返回DataFrame。 (8)skiprows:跳过指定行;skiprows=n,跳过前n行;skiprows=[a,b,c],跳过第a+1,b+1,c+1行(索引从0开始);使用skiprows后,可能会跳过行首,也就是列名。 (9)nrows:需要读取的行数,表示只读取excel的前nrows行,包括表头。 (10)skipfooter:跳过末尾n行。 ......
import pandas as pd # 读取xlsx,设置sheet位置,详细参数解释可以检索该函数 data = pd.read_excel(r"D:Desktopdata.xlsx",sheet_name=0) print(data) print(type(data)) print("*"*20) print(data.iloc[:,[0,1,3]].values) print(data.iloc[:,[0,1,3]].values.tolist()) # 输出结果 name gender age hobby 0 小红 女 20 跑步 1 小汤 男 22 篮球 2 小李 男 24 足球 3 小ai 男 21 篮球 4 小张 男 25 篮球 5 小小 男 20 跳绳 6 小耿 男 25 羽毛球 <class 'pandas.core.frame.DataFrame'> ******************** [['小红' '女' '跑步'] ['小汤' '男' '篮球'] ['小李' '男' '足球'] ['小ai' '男' '篮球'] ['小张' '男' '篮球'] ['小小' '男' '跳绳'] ['小耿' '男' '羽毛球']] [['小红', '女', '跑步'], ['小汤', '男', '篮球'], ['小李', '男', '足球'], ['小ai', '男', '篮球'], ['小张', '男', '篮球'], ['小小', '男', '跳绳'], ['小耿', '男', '羽毛球']]
(2)写入Excel文件
DataFrame.to_excel(excel_writer, sheet_name='Sheet1', na_rep='', float_format=None, columns=None, header=True, index=True, index_label=None, startrow=0, startcol=0, engine=None, merge_cells=True, encoding=None, inf_rep='inf', verbose=True, freeze_panes=None) # 参数详解 (1)excel_writer:字符串或ExcelWriter对象;文件路径或现有的ExcelWriter。 (2)sheet_name:字符串,默认"Sheet1"将包含DataFrame的表的名称。 (3)na_rep:字符串,默认''缺失数据表示方式。 (4)float_format:字符串,默认None格式化浮点数的字符串。 (5)columns:序列,可选要编写的列。 (6)header:布尔或字符串列表,默认为Ture。写出列名。如果给定字符串列表,则假定它是列名称的别名。 (7)index:布尔,默认的Ture写行名(索引)。 ......
# 用于将DataFrame对象写入Excel工作表的类。默认值是对xls使用xlwt,对xlsx使用openpyxl。 class pandas.ExcelWriter(path, engine=None, date_format=None, datetime_format=None, mode='w', **engine_kwargs) # 参数详解 (1)path:str,xls或xlsx文件的路径。 (2)engine:str (可选参数),用于编写的引擎,常见的引擎有"openpyxl"和"xlsxwriter"。如果为无,则默认为xlsxwriter,但是"xlsxwriter"模块不支持追加操作,需要追加新的sheet操作选择"openpyxl"参数,否则会报错。注意:只能作为关键字参数传递。 (3)date_format:str,默认为None,格式字符串,用于写入Excel文件的日期(例如"YYYY-MM-DD")。 (4)datetime_format:str,默认为None,写入Excel文件的日期时间对象的格式字符串。(例如"YYYY-MM-DD HH:MM:SS")。 (5)mode:{"w","a"},默认为"w",要使用的文件模式(写或追加)。 (6)if_sheet_exists:{'error','new','replace','overlay'},默认'error',写入的sheet name已存在时代码操作。默认'error'表示报错;'new'表示engine自动创建新的其他sheet name;'replace'表示覆盖原sheet数据,在写入之前删除工作表的内容;'overlay'表示将内容写入现有工作表而不删除旧内容。 为了与CSV编写器兼容,ExcelWriter在写入之前将列表和字典序列化为字符串。
在使用
pd.ExcelWriter() 的时候可能会出现问题:if_sheet_exists=‘overlay’ 不起作用查阅资料:
if_sheet_exists{'error', 'new', 'replace', 'overlay'} ,如果pandas 的版本过低,是没有overlay 参数的,需要升级pandas 版本。我的版本:pandas-2.0.1
# 追加数据 import pandas as pd name = ["小伟","小猪"] gender = ["男","男"] age = [20,18] hobby = ["跳绳","台球"] dict_data = {"name":name,"gender":gender,"age":age,"hobby":hobby} df = pd.DataFrame(dict_data) with pd.ExcelWriter(r"D:Desktopdata.xlsx", engine='openpyxl', mode='a',if_sheet_exists='overlay') as writer: df1 = pd.DataFrame(pd.read_excel(r"D:Desktopdata.xlsx", sheet_name='data')) df_rows = df1.shape[0] #获取原数据的行数 # 将数据df写入excel中的sheet1表,从第一个空行开始写 # 为了避免覆盖现有内容,要告诉to_excel方法从新的一行开始写,参数startrow设为"原行数+1" df.to_excel(writer, sheet_name='data',startrow=df_rows+1, index=False, header=False) df2 = pd.read_excel(r"D:Desktopdata.xlsx",sheet_name=0) print(df2) # 输出结果 name gender age hobby 0 小红 女 20 跑步 1 小汤 男 22 篮球 2 小李 男 24 足球 3 小ai 男 21 篮球 4 小张 男 25 篮球 5 小小 男 20 跳绳 6 小耿 男 25 羽毛球 7 小伟 男 20 跳绳 8 小猪 男 18 台球
写入
import pandas as pd import numpy as np s1 = pd.DataFrame(np.array([['s1', 's1', 's1', 's1']]), columns=['a', 'b', 'c', 'd']) s2 = pd.DataFrame(np.array([['s2', 's2', 's2', 's2']]), columns=['a', 'b', 'c', 'd']) # (1)删除文件原有数据,只保留s2一份数据(最后一份) # s1.to_excel(r"D:Desktop est.xlsx", sheet_name="111", index=False) # s2.to_excel(r"D:Desktop est.xlsx", sheet_name="222", index=False) with pd.ExcelWriter(r"D:Desktop est2.xlsx") as writer: # (2) 删除文件原有数据,同时保留s1和s2两份数据 s1.to_excel(writer, sheet_name="111", index=False) s2.to_excel(writer, sheet_name="222", index=False)
??JSON
常见的处理
{ "type": "FeatureCollection", "features": [{ "type": "Feature", "properties": {}, "geometry": { "coordinates": [[[116.3591064789793, 40.0611769097348], [116.35882714532096, 40.06035824493355], [116.3588680234169, 40.06017052423036], [116.3592154872361, 40.05968557668524], [116.35964470724883, 40.05949263960517], [116.36125939205749, 40.05968557668524], [116.36073478982053, 40.06143241456951], [116.3591064789793, 40.0611769097348]]], "type": "Polygon" } }, { "type": "Feature", "properties": {}, "geometry": { "coordinates": [116.35838429946176, 40.0595499993847], "type": "Point" } }, { "type": "Feature", "properties": {}, "geometry": { "coordinates": [116.36078873507478, 40.06152377992771], "type": "Point" } } ] }
使用
函数 | 描述 |
---|---|
将已编码的 |
|
将 |
json.loads(s, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw) # 参数详解 (1)s:要解码的JSON字符串。 (2)cls:指定用于解码JSON字符串的自定义类。 (3)object_hook:指定一个回调函数,将解码后的JSON对象转换成其他Python对象。 (4)parse_float:指定一个回调函数,将解码后的JSON浮点数转换成Python浮点数。 (5)parse_int:指定一个回调函数,将解码后的JSON整数转换成Python整数。 (6)parse_constant:指定一个回调函数,用于解析JSON中的常量(例如null,true,false)。 (7)object_pairs_hook:指定一个回调函数,将解码后的JSON对象返回为Python的键值对。
json.dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw) # 参数详解 (1)obj:转化成json的对象。 (2)skipkeys:是否跳过无法被JSON序列化的key(包括str, int, float, bool, None)。 (3)ensure_ascii:输出保证将所有输入的非ASCII字符转义。 (4)check_circular:是否检查循环引用。 (5)allow_nan:是否允许JSON规范外的float数据(nan, inf, -inf)。 (6)indent:是一个正整数, 代表序列化后的缩进。 (7)separators:是一个格式为 (item_separator, key_separator) 的元组, 默认取值为 (',',':')。 (8)default:是一个函数, 当某个value无法被序列化时, 对其调用该函数。 (9)sort_keys:是否对数据按照key进行排序。
# 读取json import json with open(r"D:Desktopmap.geojson", 'r') as f: content = f.read() a = json.loads(content) print(type(a)) print(a) print("*"*20) print(a["features"][2]["geometry"]) # 输出结果 <class 'dict'> {'type': 'FeatureCollection', 'features': [{'type': 'Feature', 'properties': {}, 'geometry': {'coordinates': [[[116.3591064789793, 40.0611769097348], [116.35882714532096, 40.06035824493355], [116.3588680234169, 40.06017052423036], [116.3592154872361, 40.05968557668524], [116.35964470724883, 40.05949263960517], [116.36125939205749, 40.05968557668524], [116.36073478982053, 40.06143241456951], [116.3591064789793, 40.0611769097348]]], 'type': 'Polygon'}}, {'type': 'Feature', 'properties': {}, 'geometry': {'coordinates': [116.35838429946176, 40.0595499993847], 'type': 'Point'}}, {'type': 'Feature', 'properties': {}, 'geometry': {'coordinates': [116.36078873507478, 40.06152377992771], 'type': 'Point'}}]} ******************** {'coordinates': [116.36078873507478, 40.06152377992771], 'type': 'Point'}
# 将字典保存成json import json a = { "type": "Feature", "properties": {}, "geometry": { "coordinates": [116.36078873507478, 40.06152377992771], "type": "Point" } } b_str = json.dumps(a) print(type(b_str)) with open(r"D:Desktop ew_json.json", 'w') as f: f.write(b_str) with open(r"D:Desktop ew_json.json", 'r') as f: content = f.read() a = json.loads(content) print(a) # 输出结果 <class 'str'> {'type': 'Feature', 'properties': {}, 'geometry': {'coordinates': [116.36078873507478, 40.06152377992771], 'type': 'Point'}}
??XML
在
xml.etree.ElementTree( 内置库):这是Python 标准库中的一个模块,提供了基本的XML 文档解析和操作功能。它具有简单的API和高效的性能,适合处理小型到中型的XML 文档。lxml :lxml 是Python 中一个功能强大的XML/HTML 解析库,基于libxml2 和libxslt 库。它提供了与ElementTree 相似的API ,但具有更好的性能和更多的功能。lxml 支持XPath 、XSLT 、XML Schema 等高级特性,适用于处理大型和复杂的XML 文档。xmltodict :xmltodict 库可以将XML 文档解析为Python 字典,使XML 数据的处理更加简便。它提供了一个简单的API ,将XML 数据转换为Python 数据结构,便于数据的操作和处理。minidom :xml.dom.minidom 是Python 标准库中的一个模块,提供了基本的DOM (文档对象模型)接口来解析和操作XML 文档。尽管它的API 相对较复杂,但它具有更多的功能和灵活性,适用于需要更高级控制的场景。
这些库都有各自的优点和适用场景。在选择库时,可以考虑以下因素:
- 对于简单的
XML 操作和小型文档,内置库xml.etree.ElementTree 是一个轻量级且易于使用的选择。- 如果需要更好的性能、更多的功能和高级特性(如
XPath 、XSLT ),可以选择lxml 库。- 如果希望将
XML 数据解析为Python 字典以便于处理,可以使用xmltodict 库。- 如果对
DOM 接口熟悉并且需要更多的灵活性和控制能力,可以考虑使用minidom 库。
# 说明 # 加载和读取xml文件,获取xml文档对象 from xml.dom import minidom doc = minidom.parse(xmlfile) # 获取xml文档根节点 root = doc.documentElement # 节点属性 root.nodeName # 每个节点都有它的nodeName,nodeValue,nodeType属性 root.nodeValue # nodeValue是节点的值,只对本节点有效 root.nodeType # 节点类型; root.ELEMENT_NODE # 属性值的获取、修改、删除 root.getAttribute(attributeName) # 获取xml节点属性值 root.setAttribute(attributeName, value) # 修改或添加xml节点属性值 root.getElementsByTagName(TagName) # 根据标签获取xml节点对象集合 root.removeAttribute(attributeName) # 删除xml节点属性值 # 子节点的访问 root.childNodes # 获取子节点列表 root.childNodes[index].nodeValue # 获取xml节点值 root.firstChild # 访问第一个节点(相当于root.childNodes[0]) root.childNodes[0].data # 获得文本值 # 删除子节点 node.removeChild(childnode_in_node) # 删除node节点下面的子节点childnode_in_node # 生成节点 node.createElement('activity') # 生成节点 # 文本节点.createTextNode('xxxxx')
(1)读取XML
<?xml version="1.0" encoding="ISO-8859-1"?> <!-- Edited by XMLSpy?? --> <breakfast_menu> <food> <name>Belgian Waffles</name> <price>$5.95</price> <calories>650</calories> <cropRegion x="0" y="0" width="0000" height="1234"/> </food> <food> <name>Strawberry Belgian Waffles</name> <price>$7.95</price> <calories>900</calories> <cropRegion x="1" y="1" width="1111" height="2345"/> </food> <food> <name>Berry-Berry Belgian Waffles</name> <price>$8.95</price> <calories>900</calories> <cropRegion x="2" y="2" width="2222" height="3456"/> </food> <food> <name>French Toast</name> <price>$4.50</price> <calories>600</calories> <cropRegion x="3" y="3" width="3333" height="4567"/> </food> <food> <name>Homestyle Breakfast</name> <price>$6.95</price> <calories>950</calories> <cropRegion x="4" y="4" width="4444" height="5678"/> </food> </breakfast_menu>
from xml.dom import minidom # 解析xml文件(句柄或文件路径) doc = minidom.parse(r"D:Desktopsimple.xml") # doc = minidom.parseString() # 解析xml字符串 print(doc) print("*"*20) # 获得根节点 root_node = doc.documentElement print(root_node) # 节点名称 print(root_node.nodeName) # 节点类型(元素节点,文本节点,属性节点) print(root_node.nodeType) # 所有子节点,为列表 print(root_node.childNodes) print("*"*20) # 通过节点名称寻找节点,返回列表 filename_node = root_node.getElementsByTagName('name') print(filename_node) print("*"*20) # 子节点为文本节点,文本节点有data属性即为文本值 filename = filename_node[1].childNodes[0].data print(filename) print("*"*20) # 读取指定属性值,root.setAttribute(attributeName, value)更新修改属性值 cropRegion_node = root_node.getElementsByTagName('cropRegion') width = cropRegion_node[1].getAttribute("width") print(width) # 输出结果 <xml.dom.minidom.Document object at 0x0000016F45D0EDC0> ******************** <DOM Element: breakfast_menu at 0x16f45d011f0> breakfast_menu 1 [<DOM Text node "' '">, <DOM Element: food at 0x16f45d01f70>, <DOM Text node "' '">, <DOM Element: food at 0x16f45d01b80>, <DOM Text node "' '">, <DOM Element: food at 0x16f45ccddc0>, <DOM Text node "' '">, <DOM Element: food at 0x16f458e0dc0>, <DOM Text node "' '">, <DOM Element: food at 0x16f45cf05e0>, <DOM Text node "' '">] ******************** [<DOM Element: name at 0x16f45d01dc0>, <DOM Element: name at 0x16f45d018b0>, <DOM Element: name at 0x16f45ccdd30>, <DOM Element: name at 0x16f45cf0af0>, <DOM Element: name at 0x16f45cf0280>] ******************** Strawberry Belgian Waffles ******************** 1111
(2)写入XML
# 写入文件 DOM树对象.writexml(fh,indent='',addindent=' ',newl=' ',encoding='UTF-8') # writexml()第一个参数是目标文件对象,第二个参数是根节点的缩进格式,第三个参数是其他子节点的缩进格式,第四个参数制定了换行格式,第五个参数制定了xml内容的编码。 # zip()函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作符,可以将元组解压为列表。 # zip()方法在Python2和Python3中的不同:在Python3.x中为了减少内存,zip()返回的是一个对象。如需展示列表,需手动list()转换。 a = [1,2,3] b = [4,5,6] c = [4,5,6,7,8] # 返回一个对象 zipped = zip(a,b) print(zipped) # list()转换为列表 print(list(zipped)) # 元素个数与最短的列表一致 print(list(zip(a,c))) # 与zip相反,*zip()函数是zip()函数的逆过程,将zip对象变成原先组合前的数据 a1 = zip(*zip(a,b)) print(a1) print(list(a1)) # 输出结果 <zip object at 0x0000016F45CD6200> [(1, 4), (2, 5), (3, 6)] [(1, 4), (2, 5), (3, 6)] <zip object at 0x0000016F45CD0FC0> [(1, 2, 3), (4, 5, 6)]
# 写入XML文件 from xml.dom import minidom # (1)创建DOM树对象 dom = minidom.Document() # (2)创建根节点,每次都要用DOM对象来创建任何节点 root_node = dom.createElement("people") # (3)用DOM对象添加根节点 dom.appendChild(root_node) # 用DOM对象创建元素字节点 name_node = dom.createElement("name") # 用父节点对象添加元素子节点 root_node.appendChild(name_node) # 设置该节点的属性 name_node.setAttribute("sex","男") name_node.setAttribute("height","180") # 用DOM创建文本节点,把文本节点(文字内容)看成子节点 name_text = dom.createTextNode("小汤") # 用添加了文本的节点对象(看成文本节点的父节点)添加文本节点 name_node.appendChild(name_text) # 用DOM对象创建元素字节点 hobby_node = dom.createElement("hobby") # 用父节点对象添加元素子节点 root_node.appendChild(hobby_node) # 用添加了文本的节点对象(看成文本节点的父节点)添加文本节点 hobby_node.appendChild(dom.createTextNode("篮球")) score_node = dom.createElement("score") for item, value in zip(["语文", "数学", "英语", "理综"], [150, 150, 150, 300]): elem = dom.createElement(item) elem.appendChild(dom.createTextNode(str(value))) score_node.appendChild(elem) root_node.appendChild(score_node) try: with open(r"D:Desktopwrite.xml",'w',encoding='UTF-8') as fh: # dom.writexml()第一个参数是目标文件对象,第二个参数是根节点的缩进格式,第三个参数是其他子节点的缩进格式, # 第四个参数制定了换行格式,第五个参数制定了xml内容的编码。 dom.writexml(fh, indent='', addindent=' ', newl=' ', encoding='UTF-8') print('OK') except Exception as err: print('错误:{err}'.format(err=err))
输出的
<?xml version="1.0" encoding="UTF-8"?> <people> <name sex="男" height="180">小汤</name> <hobby>篮球</hobby> <score> <语文>150</语文> <数学>150</数学> <英语>150</英语> <理综>300</理综> </score> </people>
??TXT
(1)读取TXT
源数据
name gender age hobby 小红 女 20 跑步 小汤 男 22 篮球 小李 男 24 足球 小ai 男 21 篮球 小张 男 25 篮球 小小 男 20 跳绳 小耿 男 25 羽毛球
操作
# (1)read()一次性读取所有文本 with open(r"D:Desktopdata.txt", "r") as f: #打开文本 data1 = f.read() #读取文本 print(data1) print("*"*20) # (2)readline()读取第一行的内容 with open(r"D:Desktopdata.txt", 'r') as f: data2 = f.readline() print(data2) print("*"*20) # (3)readlines()读取全部内容,以列表的格式返回结果 with open(r"D:Desktopdata.txt", 'r') as f: data3 = f.readlines() print(data3) for ann in data3: # 去除文本中的换行符 ann = ann.strip(' ') print(ann) print("*"*20) # (4)读取txt某一列数据,第一种方法 # 要读取第i列数据则可以读取每行的第i个数据再将其拼接起来 column_list = [] with open(r"D:Desktopdata.txt", 'r') as f: data = f.readlines() for line in data: # 去除文本中的换行符 ann = line.strip(' ') a = ann.split(" ") column_list.append(a[3]) print(column_list) print("*"*20) # (5)读取txt某一列数据,第二种方法 column_list2 = [] with open(r"D:Desktopdata.txt", 'r') as f: # 以行的形式进行读取文件 line2 = f.readline() while line2: ann2 = line2.strip(' ') aa = ann2.split(" ") column_list2.append(aa[2]) line2 = f.readline() print(column_list2) print("*"*20) # (6)读取txt某一列数据,第三种方法 import codecs column_list3 = [] with codecs.open(r"D:Desktopdata.txt", mode = 'r') as f: # 以行的形式进行读取文件 line3 = f.readline() while line3: ann3 = line3.strip(' ') aaa = ann3.split(" ") column_list3.append(aaa[1]) line3 = f.readline() print(column_list3) # 输出结果 name gender age hobby 小红 女 20 跑步 小汤 男 22 篮球 小李 男 24 足球 小ai 男 21 篮球 小张 男 25 篮球 小小 男 20 跳绳 小耿 男 25 羽毛球 ******************** name gender age hobby ******************** ['name gender age hobby ', '小红 女 20 跑步 ', '小汤 男 22 篮球 ', '小李 男 24 足球 ', '小ai 男 21 篮球 ', '小张 男 25 篮球 ', '小小 男 20 跳绳 ', '小耿 男 25 羽毛球 '] name gender age hobby 小红 女 20 跑步 小汤 男 22 篮球 小李 男 24 足球 小ai 男 21 篮球 小张 男 25 篮球 小小 男 20 跳绳 小耿 男 25 羽毛球 ******************** ['hobby', '跑步', '篮球', '足球', '篮球', '篮球', '跳绳', '羽毛球'] ******************** ['age', '20', '22', '24', '21', '25', '20', '25'] ******************** ['gender', '女', '男', '男', '男', '男', '男', '男']
(2)写入TXT
# 写入txt hobby =["hobby", "跑步", "篮球", "足球", "篮球", "篮球", "跳绳", "羽毛球"] name = ["name", "小红", "小汤", "小李", "小ai", "小张", "小小", "小耿"] age = ["age", "20", "22", "24", "21", "25", "30", "25"] with open(r"D:DesktopwriteTXT.txt","a") as f: length = len(age) for i in range(length): line = [hobby[i], name[i], age[i]] lines = " ".join(line) # lines = hobby[i] + " " + name[i] + " " + age[i] print(lines) f.write(lines + ' ') column_list = [] with open(r"D:DesktopwriteTXT.txt","r") as f: data = f.readlines() # print(data) for line in data: # 去除文本中的换行符 ann = line.strip(' ') a = ann.split(" ") column_list.append(a[2]) print(column_list) # 输出结果 hobby name age 跑步 小红 20 篮球 小汤 22 足球 小李 24 篮球 小ai 21 篮球 小张 25 跳绳 小小 30 羽毛球 小耿 25 ['age', '20', '22', '24', '21', '25', '30', '25']
多谢!多谢!
笔者不才,请多交流!!!
欢迎大家关注预览我的博客Blog:HeartLoveLife
能力有限,敬请谅解!!