利用Python处理常见文件

        常见的文件处理包括:txt、csv、json、xml、excel、pkl等等,在做竞赛的时候,数据处理是第一步,总结一点常用到的函数,方便自己查询。

一、TXT文件

1、定义

text,文本文档)是微软在操作系统上附带的一种文本格式,是最常见的一种文件格式 ,早在DOS时代应用就很多,主要存文本信息,即为文字信息,现在的操作系统大多使用记事本等程序保存,大多数软件可以查看,如记事本,浏览器等等。

2、Python读取与写入TXT文件

        要打开文件,可以使用open函数,它位于自动导入的模块os中。函数open将文件名作为唯一必不可少的参数,并返回一个文件对象。其中文件的模式包括:

函数open的参数mode的最常见取值


描述

'r'

读取模式(默认值)

'w'

写入模式

'x'

独占写入模式

'b'

二进制模式(与其他模式结合使用)

't'

文本模式(默认值,与其他模式结合使用)

'a'

附加模式

'+'

读写模式(与其他模式结合使用)

常见的函数如下:

python 处理chunked python 处理文本内容_xml文件处理

多说无益,实际例子如下:

def run(inputpath, outputpath):
    with open(outputpath, 'w', encoding='utf-8') as file:
        with open(inputpath, 'r', encoding='utf-8') as infile:
            # 第一种:读取所有行
            # data1 = infile.readlines()
            # print(data1)
            # 输出:['1 2 3 4 5 6 7 8\n', '2 4 6 8 10 12 14 16\n']

            # 第二种:每行分开读取
            data2 = []
            for line in infile:
                tmp = line[:-1].split(' ')
                data2.append([int(i) for i in tmp])
            print(data2)
            # 输出:[[1, 2, 3, 4, 5, 6, 7, 8], [2, 4, 6, 8, 10, 12, 14, 16]]

            # 写入方法
            for line in data2:
                # tmp = '' + '\t'.join(str(i) for i in line) + '\n'  # 用\t隔开
                tmp = '' + ' '.join(str(i) for i in line) + '\n'  # 用空格隔开
                file.write(tmp)
                
                
if __name__ == "__main__":
    input_path = 'test.txt'
    output_path = 'result.txt'
    run(input_path, output_path)

说明,test.txt与result.txt的文件内容一样,如下:

python 处理chunked python 处理文本内容_xml文件处理_02

 

二、CSV文件

1、定义

逗号分隔值Comma-Separated Values,CSV,有时也称为字符分隔值,因为分隔字符也可以不是逗号),其文件以纯文本形式存储表格数据(数字和文本)。纯文本意味着该文件是一个字符序列,不含必须像二进制数字那样被解读的数据。CSV文件由任意数目的记录组成,记录间以某种换行符分隔;每条记录由字段组成,字段间的分隔符是其它字符或字符串,最常见的是逗号或制表符。通常,所有记录都有完全相同的字段序列。通常都是纯文本文件。建议使用WORDPAD或是记事本来开启,再则先另存新档后用EXCEL开启,也是方法之一。 

2、规则

  • 开头是不留空,以行为单位。
  • 可含或不含列名,含列名则居文件第一行。
  • 一行数据不跨行,无空行。
  • 以半角逗号(即,)作分隔符,列为空也要表达其存在。
  • 列内容如存在半角引号(即"),替换成半角双引号("")转义,即用半角引号(即"")将该字段值包含起来。
  • 文件读写时引号,逗号操作规则互逆。
  • 内码格式不限,可为 ASCII、Unicode 或者其他。
  • 不支持数字
  • 不支持特殊字符

3、Python读取与写入CSV文件

         csv文件读取方式比较多,可以使用open函数,也可以使用pandas。首先介绍第一种:基于open函数的方法。

# 读取csv文件
def load_csv(path, encoding='utf-8', sep="\t"):
    with open(path, 'r', encoding=encoding) as file:
        lines = file.readlines()
        if sep is not None:
            lines = [line.replace("\n", "").split(sep) for line in lines]
        else:
            lines = [line.replace("\n", "") for line in lines]
        return lines


# 写入csv文件
def to_csv(data, path, encoding="utf-8", sep="\t"):
    with open(path, 'w+', encoding=encoding) as file:
        for line in data:
            file.write(sep.join(line).strip() + "\n")


# 主函数
if __name__ == "__main__":
    
    # 读取csv文件
    data = load_csv('test.csv')
    print(data)

    # 写入csv文件
    to_csv(data, 'result.csv')

举例:test.csv内容为

age,class
26,2
27,3
20,4

读入后结果:

[['age,class'], ['26,2'], ['27,3'], ['20,4']]

如果使用pandas进行数据处理呢?

import pandas as pd


datadict = {'召回率Recall': [0.66, 0.89, 0.82],
            '准确率Precision': [0.84, 0.91, 0.49],
            'F1值': [0.34, 0.13, 0.56]
            }

labels = ['other', 'A', 'B']

df = pd.DataFrame(datadict, index=labels)
print(df)

# df.to_csv('Result.csv', header=0)  # 不保存列名,header = 0
# df.to_csv('Result.csv', index=0)   # 不保留行名,index = 0
df.to_csv('Result.csv')


# 输出结果:
“”“
                  召回率Recall  准确率Precision   F1值
other                  0.66          0.84       0.34
A                      0.89          0.91       0.13
B                      0.82          0.49       0.56
”“”

 

三、JSON文件

1、定义

       JSON(JavaScript Object Notation, JS 对象简谱,读法:dʒeɪsən) 是一种轻量级的数据交换格式。它基于 ECMAScript (欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。

特点: 

  • JSON: JavaScript Object Notation(JavaScript 对象表示法)
  • JSON 是存储和交换文本信息的语法。类似 XML。
  • JSON 比 XML 更小、更快,更易解析。

2、JSON语法规则

        JSON是一个标记符的序列。这套标记符包含六个构造字符字符串数字和三个字面名。(序列化的对象数组)

2.1  六个构造字符:

begin-array = ws %x5B ws ; [ 左方括号
begin-object = ws %x7B ws ; { 左大括号
end-array = ws %x5D ws ; ] 右方括号
end-object = ws %x7D ws ; } 右大括号
name-separator = ws %x3A ws ; : 冒号
value-separator = ws %x2C ws ; , 逗号

2.2 在这六个构造字符的前或后允许存在无意义的空白符(ws):

ws = *(%x20 /; 空间
%x09 /; 水平标签
%x0A /; 换行或换行
%x0D); 回程

3、JSON的值

3.1 JSON的构成: ws  ws

3.2 可以是对象数组数字字符串或者三个字面值(false、null、true)中的一个。值中的字面值中的英文必须使用小写。

3.2.1 对象由花括号括起来的逗号分割的成员构成,成员是字符串键和上文所述的由逗号分割的键值对组成,如:

{
   "name": "John Doe", 
   "age": 18, 
   "address": {"country" : "china", "zip-code": "10000"}
}

3.2.2 数组是由方括号括起来的一组值构成,如:

[3, 1, 4, 1, 5, 9, 2, 6]

3.2.3 字符串与C或者Java的字符串非常相似。

          字符串是由双引号包围的任意数量Unicode字符的集合,使用反斜线转义。一个字符(character)即一个单独的字符串(character string)。

3.2.4 数字也与C或者Java的数值非常相似。除去未曾使用的八进制与十六进制格式。除去一些编码细节。

         一些合法的JSON的实例:

{"a": 1, "b": [1, 2, 3]}
[1, 2, "3", {"a": 4}]
3.14
"plain_text"

4、Python读取与写入JSON文件

      工作与竞赛中,经常会遇到处理这种格式的文件,如配置文件。而常用到的就是读取与写入操作,python代码如下:

import json

# 读取json文件
def load_json(path):
    with open(path, 'r', encoding='utf-8') as f:
        obj = json.load(f)
        return obj

# 写入json文件
def to_json(data, path):
    with open(path, 'w+', encoding='utf-8') as f:
        json.dump(data, f, ensure_ascii=False)


if __name__ == '__main__':

    # 读取json文件
    datadict = load_json('test.json')
    print(datadict)

    # 写入json文件
    to_json(datadict, 'result.json')

四、XML文件处理

1、定义

可扩展标记语言(eXtensible Markup Language),被设计用来传输和存储数据。XML文档的格式如下:

<?xml version="1.0" encoding="UTF-8"?>
<note>
  <to>Tove</to>
  <from>Jani</from>
  <heading>Reminder</heading>
  <body>Don't forget me this weekend!</body>
</note>

        一个xml文档必须要有第一行的声明,一般由version和encoding属性组成。 根元素(如note):它是xml文档里面唯一的;它的开始是放在最前面,结束是放在最后面。 元素:所有的xml元素都必须有结束标签(如<to>…</to>),可以按以下格式命名:

<元素名 属性名=“属性值”/>
例:<Student Age=“25”>
       <Name>Zwin</Name>
</Student>

       举个实际例子,利用Label标注的一张图像得到的xml文件内容text.xml如下:

<annotation verified="no">
	<folder>标注结果</folder>
	<filename>test.bmp</filename>
	<path>F:\3_Projects\test.bmp</path>
	<source>
		<database>Unknown</database>
	</source>
	<size>
		<width>512</width>
		<height>512</height>
		<depth>1</depth>
	</size>
	<segmented>0</segmented>
	<object>
		<name>hematencephalon</name>
		<pose>Unspecified</pose>
		<truncated>0</truncated>
		<difficult>0</difficult>
		<bndbox>
			<xmin>312</xmin>
			<ymin>168</ymin>
			<xmax>386</xmax>
			<ymax>320</ymax>
		</bndbox>
	</object>
</annotation>

2、Python读取与写入xml文件

        在Python中,主要有三种方法读写xml:基于DOM,基于ELementTree,基于SAX,详细内容,请参考博客:python中的XML读写总结。对于上面的text.xml文件,假设目标任务是:提取出xmin = 312, ymin = 168, xmax = 386, ymax = 320,并以列表的形式保存,并输出。代码是基于DOM处理的,具体如下:

import xml.dom.minidom


def main(inputpath):
    doc = xml.dom.minidom.parse(inputpath)  # dom对象
    root = doc.documentElement

    # 获取元素名为'bndbox'的对象
    objects = root.getElementsByTagName("bndbox")

    bndbox_content = []
    # 获得所有<bndbox>子元素
    for object in objects:
        print(object.nodeName, "---1")
        # 遍历输出子元素
        for item in object.childNodes:
            if item.nodeType == doc.ELEMENT_NODE:
                print(item.nodeName, "---2", end=":")
                for node in item.childNodes:
                    if node.nodeType == doc.TEXT_NODE:
                        print(node.data)
                        bndbox_content.append(item.nodeName + ":" + node.data)
    print(bndbox_content)  # 输出列表结果

if __name__ == "__main__":
    input_path = "test.xml"
    main(input_path)

运行结果:

python 处理chunked python 处理文本内容_csv文件处理_03


 

五、Excel文件处理

       有时候想自动生成一份报表,包含多个sheet,并每个sheet的内容不同,这时候可以借助openpyxl库,具体不详细介绍,举个简单的例子:(注:若在已存在的excel文件中继续添加数据)

import os
import pandas as pd
from openpyxl import load_workbook

def run(outputpath):
    # step 1: create some Pandas DateFrame from some data
    df1 = pd.DataFrame({'Data1': [1, 2, 3, 4, 5, 6, 7]})
    df2 = pd.DataFrame({'Data2': [8, 9, 10, 11, 12, 13]})

    datadict = {
        '召回率Recall': [0.66, 0.89, 0.82],
        '准确率Precision': [0.84, 0.91, 0.49],
        'F1值': [0.34, 0.13, 0.56]
    }
    labels = ['other', 'A', 'B']
    df3 = pd.DataFrame(datadict, index=labels)

    All = pd.concat([df1, df2, df3])

    # step 2: create a Pandas Excel writer using xlswriter
    if os.path.exists(outputpath): # 如果需要在已存在的Excel文件中继续添加数据,则...
        book = load_workbook(outputpath)
        writer = pd.ExcelWriter(outputpath, engine='openpyxl')
        writer.book = book
    else:  # 如果想新建或者覆盖Excel文件中的数据,则...
        writer = pd.ExcelWriter(outputpath)

    df1.to_excel(writer, sheet_name='Data1', startcol=0, index=False)
    df2.to_excel(writer, sheet_name='Data1', startcol=1, index=False)
    df3.to_excel(writer, sheet_name='意图分类结果分析')  # 若添加index = False,则表示不要第一列
    All.to_excel(writer, sheet_name='汇总')
    print("successfully!")

运行结果:

python 处理chunked python 处理文本内容_txt文件处理_04

python 处理chunked python 处理文本内容_python 处理chunked_05

python 处理chunked python 处理文本内容_xml文件处理_06

六、PKL文件处理

1、定义

  pickle(简称pkl)用于序列化和反序列化Python对象结构,也称为marshalling或flattening。 序列化是指将内存中的对象转换为可以存储在磁盘上或通过网络发送的字节流的过程。之后,这个字符流可以被检索并将其反序列化回Python对象。 Pickle不要与压缩相混淆! 前者是将对象从一种表示(随机存取存储器(RAM)中的数据)转换为另一种表示(磁盘上的文本),而后者是使用较少位编码数据的过程,以节省磁盘空间。参考:Python中的Pickle操作(pkl文件解释)

(1)pickle可以做什么?

        对于需要在数据中保持一定程度持久性的应用程序,pickle非常有用。程序的状态数据可以保存到磁盘,因此可以继续处理它。 pickle还可用于通过传输控制协议(TCP)或套接字连接(Socket)发送数据,或将python对象存储在数据库中。当使用机器学习算法时,pickle非常有用,体现在保存有效的数据,便于以后进行新的预测,而无需重新编写所有内容或重新训练模型。

(2)什么时候不能使用pickle?

        如果要使用不同编程语言的数据,建议不要使用pickle。它的协议特定于Python,因此不保证跨语言兼容性。对于不同版本的Python本身也是如此。不同版本的Python中反序列化pickle的文件可能并不总是正常工作,因此必须确保使用相同的版本并在必要时执行更新。

(3)哪些对象可以用pickle方式存取?


       可以使用以下数据类型来pickle对象:布尔值、整数,复数,(普通和Unicode)字符串,元组,列表,集合,和获取可选对象的字典。以上都可以进行Pickle操作,同时也可对类和函数执行相同的操作。然而,并非所有东西都可以被轻易pickle:例如,生成器,内部类,lambda函数和默认值。 对于lambda函数,需要使用名为dill的附加包。 使用defaultdicts,需要使用模块级函数来创建。

2、python代码

import pickle as pk
import pandas as pd


# 加载pkl文件
def load_pkl(input_path):
    with open(input_path, 'rb') as f:
        loaded_obj = pk.load(f)
    return loaded_obj


# 写入pkl文件
def to_pkl(content, output_path):
    with open(output_path, 'wb') as f:
        pk.dump(content, f)


def run():

    some_obj = {'x': [4, 2, 1.5, 1],
                'y': [32, [101], 17],
                '好人': True,
                'spam': False}

    pickle_file = 'pickle1.pkl'

    # 第一种写入pkl文件方式,利用pandas中的函数
    pd.to_pickle(some_obj, pickle_file)

    # 第二种写入pkl文件方式
    to_pkl(some_obj, pickle_file)
    print('successfully!')

    # 第一种读取pkl文件方式,利用pandas中的函数
    df = pd.read_pickle(pickle_file)
    print(df)

    # 第二种读取pkl文件方式
    res = load_pkl(pickle_file)
    print(res)


if __name__ == "__main__":
    run()

 

参考文献:

(1)十分钟入门pandas——官网中文教程