第7章 文件和数据格式化

来自CloudWiki
跳转至: 导航搜索

文件的使用

文件的类型

文件包括文本文件和二进制文件两种类型。

文本文件一般由单一特定编码的字符串组成,如如一个txt格式的文本文件。

二进制文件直接由比特0和皮特一组成,没有统一的字符编码。二进制文件由于没有统一的字符编码,只能当做字节流,而不能看作是字符串。

例题:

#写文件
s = 'Hello world\n文本文件的读取方法\n文本文件的写入方法\n'
fw = open('sample.txt',"wt")
fw.write(s)
fw.close()

#以文本形式读文件
fr =open('sample.txt',"rt")
print(fr.read())
fr.close()

#以二进制形式读文件
fr =open('sample.txt',"rb")
print(fr.read())
fr.close()


文件的打卡和关闭

open函数的格式

open(file, mode='r', buffering=-1, encoding=None, errors=None,newline=None, closefd=True, opener=None)

  • file参数指定了被打开的文件名称。
  • mode参数指定了打开文件后的处理方式。
  • buffering参数指定了读写文件的缓存模式。0表示不缓存,1表示缓存,如大于1则表示缓冲区的大小。默认值是缓存模式。
  • encoding参数指定对文本进行编码和解码的方式,只适用于文本模式,可以使用Python支持的任何格式,如GBK、utf8、CP936等等。

文件打开模式

文件打开模式:

  • Python7-1.png

使用方法

  • 如果执行正常,open()函数返回1个文件对象,通过该文件对象可以对文件进行读写操作。如果指定文件不存在、访问权限不够、磁盘空间不足或其他原因导致创建文件对象失败则抛出异常。
f1 = open( 'file1.txt', 'r' )     # 以读模式打开文件
f2 = open( 'file2.txt', 'w')      # 以写模式打开文件
  • 当对文件内容操作完以后,一定要关闭文件对象,这样才能保证所做的任何修改都确实被保存到文件中。
f1.close()

例题:

s = 'Hello world\n文本文件的读取方法\n文本文件的写入方法\n'
fw = open('sample.txt',"w")
fw.write(s)
fw.close()

fr =open('sample.txt',"r")
print(fr.read())
fr.close()
 

上下文管理语句with

在实际开发中,读写文件应优先考虑使用上下文管理语句with,关键字with可以自动管理资源,不论因为什么原因(哪怕是代码引发了异常)跳出with块,总能保证文件被正确关闭,并且可以在代码块执行完毕后自动还原进入该代码块时的上下文,常用于文件操作、数据库连接、网络连接、多线程与多进程同步时的锁对象管理等场合。

 with open(filename, mode, encoding) as fp:
    #这里写通过文件对象fp读写文件内容的语句

  • 上下文管理语句with还支持下面的用法:
with open('test.txt', 'r') as src, open('test_new.txt', 'w') as dst:
	dst.write(src.read())

所以,上面那个例子用上下文语句可以这么写:

s = 'Hello world\n文本文件的读取方法\n文本文件的写入方法\n'
with open('sample.txt',"w") as fw:
    fw.write(s)

with open('sample.txt',"r") as fr:
    print(fr.read())

文件的读写操作

文件的类型

如果文件不大,可以一次性将文件内容读入,保存到程序内部变量当中,f.read()是最常用的一次性读文件的函数。

#写文件
s = '新年都未有芳华,二月初惊见草芽。白雪却嫌春色晚。故穿庭树作飞花。'
fw = open('D:/sample.txt',"wt")
fw.write(s)
fw.close()

#以文本形式读文件
fr =open('D:/sample.txt',"rt")
print(fr.readlines())
fr.close()


#以二进制形式读文件
fr =open('D:/sample.txt',"rb")
print(fr.readlines())
fr.close()

f.readlines()也是一次性读入文件的函数,其结果是一个列表,每个元素是文件的一行。

fr =open('D:/sample.txt',"rt")
print(fr.readlines())
fr.close()

当从文件中读取内容后,读取指针将向前进,可以用seek()方法将读取指针移动到文件开头

#写文件
s = '新年都未有芳华,二月初惊见草芽。白雪却嫌春色晚。故穿庭树作飞花。'
fw = open('D:/sample.txt',"wt")
fw.write(s)
fw.close()

#以文本形式读文件
fr =open('D:/sample.txt',"rt")
s=fr.read()

print(s)

#fr.seek(0)

s=fr.read()
print(s)
fr.close()

文本文件可以看作是由行组成的组合类型,因此也可以使用遍历循环逐行的遍历文件。

s = '新年都未有芳华,\n二月初惊见草芽。\n白雪却嫌春色晚。\n故穿庭树作飞花。'
fw = open('sample.txt',"wt")
fw.write(s)
fw.close()

fp =open('sample.txt',"rt")      #假设文件采用CP936编码
for line in fp:                 #文件对象可以直接迭代
    print(line)
fp.close()

写操作

f.write()向文件写入字符串,每次写入后,将会记录一个写入指针。

f = open("D:/test.txt","w")
f.write("新年都未有芳华。\n")
f.write("2月初惊见草芽。\n")
f.write("白雪却嫌春色晚。\n")
f.write("故穿庭树作飞花。\n")
f.close()

fp =open('D:/test.txt',"rt")      
for line in fp:                 #文件对象可以直接迭代
    print(line)
fp.close()

f.writelines()直接将列表类型的各个元素连接起来,写入文件。

f = open("D:/test.txt","w")
#f.write("新年都未有芳华。\n")
#f.write("2月初惊见草芽。\n")
#f.write("白雪却嫌春色晚。\n")
#f.write("故穿庭树作飞花。\n")
ls = ['新年都未有芳华,\n二月初惊见草芽。\n白雪却嫌春色晚。\n故穿庭树作飞花。\n']
f.writelines(ls)
f.close()

fp =open('D:/test.txt',"rt")      
for line in fp:                 #文件对象可以直接迭代
    print(line)
fp.close()

数据组织的维度

一维数据

二维数据

高维数据

一维数据的处理

一维数据的表示

>>> ls=['北京','上海','天津','重庆']
>>> print(ls)
['北京', '上海', '天津', '重庆']

一维数据的存储

通常使用这种格式来存储一位数据。

北京,上海,天津,重庆

这种用逗号分隔的存储格式叫做CS规格是,它是一种通用的,相对简单的文件格式,在商业和科学上广泛应用,甚至能被Excel软件打开。注意这里的逗号,一定是英文逗号。

ls=['北京','上海','天津','重庆']
f = open("city.csv","w")
f.write(",".join(ls)+"\n")
f.close()

一维数据的处理

需要注意从CSv文件中获得内容时,最后一个元素后面包含了一个换行符,对于数据的表达和使用来说,这个换行符是多余的,需要采用字符串的strip()方法,去除数据尾部的换行符,进一步使用方法split()方法,以逗号进行分割。

f = open("city.csv","r")
ls = f.read().strip('\n').split(",")
f.close()
print(ls)


二维数据的处理

二维数据的表示

二维数据由多个一维数据构成,可以看作是一维数据的组合形式。因此,二维数据可以采用二维列表来表示。

ls = [
        ['指标','2014年','2015年','2016年'],
        ['居民消费价格指数','102','101.4','102'],
        ['食品','103.1','102.3','104.6'],
        ['烟酒及用品','99.4','102.1','101.5'],
     ]

二维数据的存储

f = open("cpi.csv","w")
for row in ls:
    f.write(",".join(row)+"\n")

f.close( )

二维数据的处理

f = open("cpi.csv","r")

bs = []
for line in f:
    bs.append(line.strip('\n').split(","))

f.close()
print(bs)

实例:国家财政数据趋势演算

国家统计局每年会公开许多数据,比如国民经济核算指标等,这些数据可以从如下获得。

https://share.weiyun.com/5ckrJ80

统计局公布的大部分数据都以二维表格形式展现,然而,我们怎样从这些二维表格当中读取数据,并把数据展现出来呢?

  • parseCSV:读取数据
  • showResults:展现数据
  • main: 主函数
# FinancePredict.py
def parseCSV(filename):
    dataNames, data = [], []
    f = open(filename, 'r', encoding='utf-8')
    for line in f:
        splitedLine = line.strip().split(',')
        if '指标' in splitedLine[0]:
            years = [int(x[:-1]) for x in splitedLine[1:]]
        else:
            dataNames.append('{:10}'.format(splitedLine[0]))
            data.append([float(x) for x in splitedLine[1:]])
    f.close()
    return years, dataNames, data    

    
def showResults(years, dataNames, newDatas):
    print('{:^60}'.format('国家财政收支线性估计'))
    header = '指标       '
    for year in years:
        header += '{:10}'.format(year)
    print(header)
    for name, lineData in zip(dataNames, newDatas):
        line = name
        for data in lineData:
            line += '{:>10.1f}'.format(data)
        print(line)
    
def main():
    newyears = [x+2010 for x in range(7)]
    newDatas = []
    years, dataNames, datas = parseCSV('finance.csv')
    
    showResults(years, dataNames, datas)
    
main()