Python学习笔记(七)

作者: jplee | 来源:发表于2017-07-26 16:12 被阅读51次

    第七章 文件和数据格式化

    文件的使用

    文件概述

    文件是一个存储在辅助存储器上的数据序列,可以包含任何数据内容。概念上,文件是数据的集合和抽象,类似地,函数是程序的集合和抽象。用文件形式组织和表达数据更有效也更为灵活。文件包括两种类型:文本文件和二进制文件。
    二进制文件直接由比特0和比特1组成,没有统一字符编码,文件内部数据的组织格式与文件用途有关。二进制文件和文本文件最主要的区别在于是否有统一的字符编码
    无论文件创建为文本文件或者二进制文件,都可以用“文本文件方式”和“二进制文件方式”打开,打开后的操作不同。

    #理解文本文件和二进制文件的区别
    textFile = open("f:/Code/Python/PythonCourse/7-1.txt","rt") #t表示文本文件方式
    print(textFile.readline())
    textFile.close()
    binFile = open("f:/Code/Python/PythonCourse/7-1.txt","rb")   #r表示二进制文件方式
    print(binFile.readline())
    binFile.close()
    
    
    中国是个伟大的国家
    b'\xd6\xd0\xb9\xfa\xca\xc7\xb8\xf6\xce\xb0\xb4\xf3\xb5\xc4\xb9\xfa\xbc\xd2'
    

    采用文本方式读入文件,文件经过编码形成字符串,打印出有含义的字符;采用二进制方式打开文件,文件被解析为字节(byte)流。由于存在编码,字符串中的一个字符由2个字节表示。

    文件的打开关闭

    Python对文本文件和二进制文件采用统一的操作步骤,即“打开-操作-关闭”
    Python通过解释器内置的open()函数打开一个文件,并实现该文件与一个程序变量的关联,open()函数格式如下:

    <变量名> = open(<文件名>, <打开模式>)  
    

    open()函数有两个参数:文件名和打开模式。文件名可以是文件的实际名字,也可以是包含完整路径的名字
    open()函数有7中基本的打开模式

    文件的读写

    根据打开方式不同可以对文件进行相应的读写操作,Python提供4个常用的文件内容读取方法

    #文本文件逐行打印
    fname = input("请输入要打开的文件: ")
    fo = open(fname, "r")
    for line in fo.readlines():
        print(line)
    fo.close()
    
    
    请输入要打开的文件: f:/code/Python/PythonCourse/7-2.txt
    中国是个伟大的国家!
    
    中国地大物博
    
    中国有五千年的文明
    
    fname = input("请输入要打开的文件: ")
    fo = open(fname, "r")
    for line in fo:
        print(line)
    fo.close()
    
    
    请输入要打开的文件: f:/code/Python/PythonCourse/7-2.txt
    中国是个伟大的国家!
    
    中国地大物博
    
    中国有五千年的文明
    

    如果程序需要逐行处理文件内容,建议采用上述代码格式:

    fo = open(fname, "r")
    for line in fo:
        # 处理一行数据
    fo.close()
    

    Python提供3个与文件内容写入有关的方法

    fname = input("请输入要写入的文件: ") 
    fo = open(fname, "w+")
    ls = ["唐诗", "宋词", "元曲"]
    fo.writelines(ls)
    fo.close()
    
    f=open(fname,"r")
    for line in f:
        print(line)
    f.close()
    
    
    请输入要写入的文件: f:/code/Python/PythonCourse/test.txt
    唐诗宋词元曲
    

    PIL库的使用

    PIL库概述

    PIL(Python Image Library)库是Python语言的第三方库,需要通过pip工具安装。

    pip install pillow   # 或者 pip3 install pillow
    

    PIL库支持图像存储、显示和处理,它能够处理几乎所有图片格式,可以完成对图像的缩放、剪裁、叠加以及向图像添加线条、图像和文字等操作。
    PIL库可以完成图像归档和图像处理两方面功能需求:

    • 图像归档:对图像进行批处理、生成图像预览、图像格式转换等;
    • 图像处理:图像基本处理、像素处理、颜色处理等。

    PIL库Image类解析

    在PIL中,任何一个图像文件都可以用Image对象表示
    要加载一个图像文件,最简单的形式如下,之后所有操作对im起作用

    from PIL import Image
    im = Image.open("D:\\pycodes\\birdnest.jpg")
    
    #GIF文件图像提取
    #对一个GIF格式动态文件,提取其中各帧图像,并保存为文件。
    from PIL import Image
    im = Image.open('f:/PythonCourse/birdnest.gif')      # 读入一个GIF文件
    try:
        im.save('f:/PythonCourse/picframe{:02d}.png'.format(im.tell()))
        while True:
            im.seek(im.tell()+1)
            im.save('f:/PythonCourse/picframe{:02d}.png'.format(im.tell()))
    except Exception as e:
        print(e)
        print("处理结束")
    
    
    no more images in GIF file
    处理结束
    
    #图像的颜色交换
    #交换图像中的颜色。可以通过分离RGB图片的三个颜色通道实现颜色交换
    from PIL import Image
    im = Image.open('f:/PythonCourse/birdnest.jpg')
    r, g, b = im.split()
    om = Image.merge("RGB", (b, g, r))
    om.save('f:/PythonCourse/birdnestBGR.jpg')
    
    
    #操作图像的每个像素点需要通过函数实现,采用lambda函数和point()方法搭配使用
    im = Image.open('f:/PythonCourse/birdnest.jpg') #打开鸟巢文件
    r, g, b = im.split() #获得RGB通道数据
    newg = g.point(lambda i: i * 0.9) # 将G通道颜色值变为原来的0.9倍
    newb = b.point(lambda i: i < 100) # 选择B通道值低于100的像素点
    om = Image.merge(im.mode, (r, newg, newb)) # 将3个通道合形成新图像
    om.save('f:/PythonCourse/birdnestMerge.jpg') #输出图片
    
    

    图像的过滤和增强

    PIL库的ImageFilter类和ImageEnhance类提供了过滤图像和增强图像的方法,共10种
    利用Image类的filter()方法可以使用ImageFilter类,如下:
    Image.filter(ImageFilter.fuction)

    #图像的轮廓获取
    from PIL import Image
    from PIL import ImageFilter
    im = Image.open('f:/PythonCourse/birdnest.jpg')
    om = im.filter(ImageFilter.CONTOUR)
    om.save('f:/PythonCourse/birdnestContour.jpg')
    
    

    ImageEnhance类提供了更高级的图像增强需求,它提供调整色彩度、亮度、对比度、锐化等功能。

    #图像的对比度增强。
    #增强图像的对比度为初始的20倍。
    from PIL import Image
    from PIL import ImageEnhance
    im = Image.open('f:/PythonCourse/birdnest.jpg')
    om = ImageEnhance.Contrast(im)
    om.enhance(20).save('f:/PythonCourse/birdnestEnContrast.jpg')
    
    

    图像字符画绘制

    位图图片是由不同颜色像素点组成的规则分布,如果采用字符串代替像素,图像就成为了字符画。
    定义一个字符集,将这个字符集替代图像中的像素点。

    ascii_char =list("$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjf1234568795t/\|()1{}[]?-_+~<>i!;:,\"^`'.")
    

    定义彩色向灰度的转换公式如下,其中R、G、B分别是像素点的RGB颜色值:
    Gray = R * 0.2126 + G * 0.7152 + B * 0.0722
    因此,像素的RGB颜色值与字符集的对应函数如下:

    def get_char(r, b, g, alpha=256):
        if alpha == 0:
            return ' '
        gray = int(0.2126 * r + 0.7152 * g + 0.0722 * b)
        unit = 256 / len(ascii_char)
        return ascii_char[gray//unit]
    
    
    from PIL import Image
    ascii_char  = list('"$%_&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-/+@<>i!;:,\^`.')
    def get_char(r, b, g, alpha=256):
        if alpha == 0:
            return ' '
        gray = int(0.2126 * r + 0.7152 * g + 0.0722 * b)
        unit = 256 / len(ascii_char)
        return ascii_char[int(gray//unit)]
    def main():
        im = Image.open('f:/PythonCourse/pic.jpg')
        WIDTH, HEIGHT = 100, 60
        im = im.resize((WIDTH, HEIGHT))
        txt = ""
        for i in range(HEIGHT):
            for j in range(WIDTH):
                txt += get_char(*im.getpixel((j, i)))
            txt += '\n'
        fo = open("f:/PythonCourse/pic_char.txt","w")
        fo.write(txt)
        fo.close()
    main()
    
    

    一二维数据格式化和处理

    数据组织的维度

    一维数据由对等关系的有序或无序数据构成,采用线性方式组织,对应于数学中的数组和集合等概念。
    二维数据,也称表格数据,由关联关系数据构成,采用表格方式组织,对应于数学中的矩阵,常见的表格都属于二维数据。
    高维数据由键值对类型的数据构成,采用对象方式组织,属于整合度更好的数据组织方式。高维数据在网络系统中十分常用,HTML、XML、JSON等都是高维数据组织的语法结构

    一二维数据的存储格式

    一维数据是最简单的数据组织类型,有多种存储格式,常用特殊字符分隔:
    (1)用一个或多个空格分隔,例如:
    中国 美国 日本 德国 法国 英国 意大利
    (2)用逗号分隔,例如:
    中国,美国,日本,德国,法国,英国,意大利
    (3)用其他符号或符号组合分隔,建议采用不出现在数据中的特殊符号
    中国; 美国; 日本; 德国; 法国; 英国; 意大利

    逗号分割数值的存储格式叫做CSV格式(Comma-Separated Values,即逗号分隔值),它是一种通用的、相对简单的文件格式,在商业和科学上广泛应用,尤其应用在程序之间转移表格数据。
    (1)纯文本格式,通过单一编码表示字符;
    (2)以行为单位,开头不留空行,行之间没有空行;
    (3)每行表示一个一维数据,多行表示二维数据;
    (4)以逗号分隔每列数据,列数据为空也要保留逗号;
    (5)可以包含或不包含列名,包含时列名放置在文件第一行。

    二维数据采用CSV存储后的内容如下:
    城市,环比,同比,定基
    北京,101.5,120.7,121.4
    上海,101.2,127.3,127.8
    广州,101.3,119.4,120
    深圳,102,140.9,145.5
    沈阳,100.1,101.4,101.6
    CSV格式存储的文件一般采用.csv为扩展名,可以通过Windows平台上的记事本或微软Office Excel工具打开,也可以在其他操作系统平台上用文本编辑工具打开。

    一二维数据的表示和读写

    CSV文件的每一行是一维数据,可以使用Python中的列表类型表示,整个CSV文件是一个二维数据,由表示每一行的列表类型作为元素,组成一个二维列表。

    [   
    ['城市', '环比', '同比', '定基'], 
    ['北京', '101.5', '120.7', '121.4'], 
    ['上海', '101.2', '127.3', '127.8'], 
    ['广州', '101.3', '119.4', '120.0'], 
    ['深圳', '102.0', '140.9', '145.5'],
    ['沈阳', '100.1', '101.4', '101.6'] 
    ]
    
    l = [
    ['城市', '环比', '同比', '定基'], 
    ['北京', '101.5', '120.7', '121.4'], 
    ['上海', '101.2', '127.3', '127.8'], 
    ['广州', '101.3', '119.4', '120.0'], 
    ['深圳', '102.0', '140.9', '145.5'],
    ['沈阳', '100.1', '101.4', '101.6'] 
    ]
    f = open("f:/PythonCourse/price2016.csv","w")
    for ll in l:
        f.write(",".join(ll)+ "\n")
    f.close()
    
    #导入CSV格式数据到列表
    fo = open("f:/PythonCourse/price2016.csv", "r")
    ls = []
    for line in fo:
        line = line.replace("\n","")
        ls.append(line.split(","))
    print(ls)
    fo.close()
    
    
    [['城市', '环比', '同比', '定基'], ['北京', '101.5', '120.7', '121.4'], ['上海', '101.2', '127.3', '127.8'], ['广州', '101.3', '119.4', '120.0'], ['深圳', '102.0', '140.9', '145.5'], ['沈阳', '100.1', '101.4', '101.6']]
    

    需要注意,以split(",")方法从CSV文件中获得内容时,每行最后一个元素后面包含了一个换行符("\n")。对于数据的表达和使用来说,这个换行符是多余的,可以通过使用字符串的replace()方法将其去掉,如第4行。

    #逐行处理CSV格式数据。
    fo = open("f:/PythonCourse/price2016.csv", "r")
    ls = []
    for line in fo:
        line = line.replace("\n","")
        ls = line.split(",")
        lns = ""
        for s in ls:
              lns += "{}\t".format(s)
        print(lns)
    fo.close()
    
    
    城市  环比  同比  定基  
    北京  101.5   120.7   121.4   
    上海  101.2   127.3   127.8   
    广州  101.3   119.4   120.0   
    深圳  102.0   140.9   145.5   
    沈阳  100.1   101.4   101.6   
    
    #一维数据写入CSV文件
    fo = open("f:/PythonCourse/price2016bj.csv", "w")
    ls = ['北京', '101.5', '120.7', '121.4']
    fo.write(",".join(ls)+ "\n")
    fo.close()
    
    

    对于列表中存储的二维数据,可以通过循环写入一维数据的方式写入CSV文件,参考代码样式如下:

    for row in ls:
    
          <输出文件>.write(",".join(row)+"\n")
    
    #二维数据写入CSV文件
    fr = open("f:/PythonCourse/price2016.csv", "r")
    fw = open("f:/PythonCourse/price2016out.csv", "w")
    ls = []
    for line in fr:     #将CSV文件中的二维数据读入到列表变量
        line = line.replace("\n","")
        ls.append(line.split(","))
    for i in range(len(ls)):   #遍历列表变量计算百分数
        for j in range(len(ls[i])):
            if ls[i][j].replace(".","").isnumeric():
                ls[i][j] = "{:.2}%".format(float(ls[i][j])/100)
    for row in ls:    #将列表变量中的二位数据输出到CSV文件
        print(row)
        fw.write(",".join(row)+"\n")
    fr.close()
    fw.close()
    
    
    ['城市', '环比', '同比', '定基']
    ['北京', '1.0%', '1.2%', '1.2%']
    ['上海', '1.0%', '1.3%', '1.3%']
    ['广州', '1.0%', '1.2%', '1.2%']
    ['深圳', '1.0%', '1.4%', '1.5%']
    ['沈阳', '1.0%', '1.0%', '1.0%']
    

    CSV格式的HTML展示

    展示二位数据的对应的HTML代码:

    <!DOCTYPE HTML>
    <html>
    <body>
    <meta charset=utf-8>
    <h2 align=center>2016年7月部分大中城市新建住宅价格指数</h2>
    <table border='1' align=center width=70%>
    <tr bgcolor='orange'>
    <th width="25%">城市</th>
    <th width="25%">环比</th>
    <th width="25%">同比</th>
    <th width="25%">定基</th>
    </tr>
    <tr><td>北京</td><td>101.5</td><td>120.7</td><td>121.4</td></tr>
    <tr><td>上海</td><td>101.2</td><td>127.3</td><td>127.8</td></tr>
    <tr><td>广州</td><td>101.3</td><td>119.4</td><td>120.0</td></tr>
    <tr><td>深圳</td><td>102.0</td><td>140.9</td><td>145.5</td></tr>
    <tr><td>沈阳</td><td>100.1</td><td>101.4</td><td>101.6</td></tr>
    </table>
    </body>
    </html>
    
    seg1 = '''
    <!DOCTYPE HTML>\n<html>\n<body>\n<meta charset=gb2312>
    <h2 align=center>2016年7月部分大中城市新建住宅价格指数</h2>
    <table border='1' align="center" width=70%>
    <tr bgcolor='orange'>\n '''
    seg2 = "</tr>\n"
    seg3 = "</table>\n</body>\n</html>"
    def fill_data(locls):
        seg = '<tr><td align="center">{}</td><td align="center">\
        {}</td><td align="center">{}</td><td align="center">\
        {}</td></tr>\n'.format(*locls)
        return seg
    fr = open("f:/PythonCourse/price2016.csv", "r")
    ls = []
    for line in fr:
        line = line.replace("\n","")
        ls.append(line.split(","))
    print(ls)
    fr.close()
    fw = open("f:/PythonCourse/price2016.html", "w")
    fw.write(seg1)
    fw.write('<th width="25%">{}</th>\n<th width="25%">{}</th>\n<th width="25%">{}</th>\n<th width="25%">{}</th>\n'.format(*ls[0]))
    fw.write(seg2)
    for i in range(len(ls)-1):
        fw.write(fill_data(ls[i+1]))
    fw.write(seg3)
    fw.close()
    
    
    [['城市', '环比', '同比', '定基'], ['北京', '101.5', '120.7', '121.4'], ['上海', '101.2', '127.3', '127.8'], ['广州', '101.3', '119.4', '120.0'], ['深圳', '102.0', '140.9', '145.5'], ['沈阳', '100.1', '101.4', '101.6']]
    

    高维数据的格式化

    与一维二维数据不同,高维数据能展示数据间更为复杂的组织关系。为了保持灵活性,表示高维数据不采用任何结构形式,仅采用最基本的二元关系,即键值对。万维网是高维数据最成功的典型应用。
    JSON格式可以对高维数据进行表达和存储。JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于阅读和理解。JSON格式表达键值对基本格式如下,键值对都保存在双引号中:
    "key" : "value"
    当多个键值对放在一起时,JSON有如下一些约定:

    • 数据保存在键值对中;
    • 键值对之间由逗号分隔;
    • 括号用于保存键值对数据组成的对象;
    • 方括号用于保存键值对数据组成的数组。
    "本书作者" : [  
    {   "姓氏" : "嵩",
    "名字" : "天",
    "单位" : "北京理工大学"   }, 
    {   "姓氏" : "礼",
    "名字" : "欣",
    "单位" : "北京理工大学"   },
    {   "姓氏" : "黄",
    "名字" : "天羽",
    "单位" : "北京理工大学"   }  
    ]
    

    json库的使用

    Json库的概述

    json库主要包括两类函数:操作类函数和解析类函数

    • 操作类函数主要完成外部JSON格式和程序内部数据类型之间的转换功能
    • 解析类函数主要用于解析键值对内容。

    Json库的解析

    dumps()和loads()分别对应编码和解码功能。

    import json
    dt = {'b':2,'c':4,'a':6}
    s1 = json.dumps(dt)  #dumps返回JSON格式的字符串类型
    s2 = json.dumps(dt,sort_keys=True,indent=4)
    print(s1)
    print(s2)
    print(s1==s2)
    dt2 = json.loads(s2)
    print(dt2, type(dt2))
    
    
    {"b": 2, "c": 4, "a": 6}
    {
        "a": 6,
        "b": 2,
        "c": 4
    }
    False
    {'a': 6, 'b': 2, 'c': 4} <class 'dict'>
    

    CSV和JSON格式相互转换

    CSV格式常用于一二维数据表示和存储,JSON也可以表示一二维数据。在网络信息传输中,可能需要统一表示方式,因此,需要在CSV和JSON格式间进行相互转换。

    #将CSV转换成JSON格式的代码如下 
    import json
    fr = open("f:/PythonCourse/price2016.csv", "r")
    ls = []
    for line in fr:
        line = line.replace("\n","")
        ls.append(line.split(','))
    fr.close()
    fw = open("f:/PythonCourse/price2016.json", "w")
    for i in range(1,len(ls)):
        ls[i] = dict(zip(ls[0], ls[i]))
    json.dump(ls[1:],fw, sort_keys=True, indent=4)
    fw.close()
    
    
    #将二维JSON格式数据转换成CSV格式
    import json
    fr = open("f:/PythonCourse/price2016.json", "r")
    ls = json.load(fr)
    data = [ list(ls[0].keys()) ]
    for item in ls:
        data.append(list(item.values()))
    fr.close()
    fw = open("f:/PythonCourse/price2016_from_json.csv", "w")
    for item in data:
        fw.write(",".join(item) + "\n")
    fw.close()
    
    
    
    

    相关文章

      网友评论

        本文标题:Python学习笔记(七)

        本文链接:https://www.haomeiwen.com/subject/bklokxtx.html