Python學習筆記(七)

第七章 文件和數據格式化

文件的使用

文件概述

文件是一個存儲在輔助存儲器上的數據序列,可以包含任何數據內容。概念上,文件是數據的集合和抽象,類似地,函數是程序的集合和抽象。用文件形式組織和表達數據更有效也更為靈活。文件包括兩種類型:文本文件和二進制文件。
二進制文件直接由比特0和比特1組成,沒有統一字符編碼,文件內部數據的組織格式與文件用途有關。二進制文件和文本文件最主要的區(qū)別在于是否有統一的字符編碼
無論文件創(chuàng)建為文本文件或者二進制文件,都可以用“文本文件方式”和“二進制文件方式”打開,打開后的操作不同。

#理解文本文件和二進制文件的區(qū)別
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'

采用文本方式讀入文件,文件經過編碼形成字符串,打印出有含義的字符;采用二進制方式打開文件,文件被解析為字節(jié)(byte)流。由于存在編碼,字符串中的一個字符由2個字節(jié)表示。

文件的打開關閉

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格式動態(tài)文件,提取其中各幀圖像,并保存為文件。
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通道顏色值變?yōu)樵瓉淼?.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')

圖像字符畫繪制

位圖圖片是由不同顏色像素點組成的規(guī)則分布,如果采用字符串代替像素,圖像就成為了字符畫。
定義一個字符集,將這個字符集替代圖像中的像素點。

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,即逗號分隔值),它是一種通用的、相對簡單的文件格式,在商業(yè)和科學上廣泛應用,尤其應用在程序之間轉移表格數據。
(1)純文本格式,通過單一編碼表示字符;
(2)以行為單位,開頭不留空行,行之間沒有空行;
(3)每行表示一個一維數據,多行表示二維數據;
(4)以逗號分隔每列數據,列數據為空也要保留逗號;
(5)可以包含或不包含列名,包含時列名放置在文件第一行。

二維數據采用CSV存儲后的內容如下:
城市,環(huán)比,同比,定基
北京,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文件是一個二維數據,由表示每一行的列表類型作為元素,組成一個二維列表。

[   
['城市', '環(huán)比', '同比', '定基'], 
['北京', '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 = [
['城市', '環(huán)比', '同比', '定基'], 
['北京', '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()

[['城市', '環(huán)比', '同比', '定基'], ['北京', '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()

城市  環(huán)比  同比  定基  
北京  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()

對于列表中存儲的二維數據,可以通過循環(huán)寫入一維數據的方式寫入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()

['城市', '環(huán)比', '同比', '定基']
['北京', '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%">環(huán)比</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()

[['城市', '環(huán)比', '同比', '定基'], ['北京', '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()


最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容