在进行数据处理分析和计算之前的首要步骤就是先把数据读进你的内存中,那么这一个部分就主要讲解如何使用Python来读取你的数据。
作者
header: 本文撰写工作已经
同步发布至知乎专栏:建模数学
系列文章(科学计算Python2小时)目录:https://zhuanlan.zhihu.com/p/347573688zhuanlan.zhihu.com
这里我们主要讨论4种数据存储的方式,以及如何把他们从文件中读取出来,分别是txt、csv、json、xls这里面txt是我们非常常见的一种存储纯文本数据的方法,通常使用记事本就可以把它们轻松的打开(因为里面存的就是字符串)。当然,其实前三种文件格式都能够用记事本打开。他一般用来存储一些非结构化的零散的数据。
如果提供的数据分成了很多条目,并且每一个条目中包含的数据类别都是一样的,那么它一般会使用csv来进行文件的存储,csv是一种利用逗号来进行数据分割(字符分割)的存储结构或者叫文件类型。此外,第3种数据存储方法叫做json.它是一种在互联网上非常常用的传递结构化信息的方式。如果你要传递的信息比较复杂,每一个条目包含的数据类别分别不同,甚至会有多重的嵌套,那么使用json来存储和传递信息是非常简便的方法。xls或者xlsx这是我们非常常见和常用的Excel的数据格式这里不再赘述。
txt:
with open("txtFileTest.txt","r") as txtFile:
print(txtFile.read().replace("\n"," "))
# 这里正常输出应该是每个数字一行的,但是为了展示的方便,就把换行符换成了空格来输出(\n是换行)
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
with open("txtFileTest.txt","r") as txtFile:
print(txtFile.readline())
print(txtFile.readline())
print(txtFile.readline())
0 1 2
with open("txtFileTest.txt","r") as txtFile:
print(txtFile.readlines())
['0\n', '1\n', '2\n', '3\n', '4\n', '5\n', '6\n', '7\n', '8\n', '9\n', '10\n', '11\n', '12\n', '13\n', '14\n', '15\n', '16\n', '17\n', '18\n', '19\n', '20\n']
说明使用了三种方法来读取文件中的内容,当然打开文件的方法都是一致的,使用with as 结构是一种很好的习惯,他能够在这个代码段结束之后自动的关闭文件。避免了,我们还要手动的去执行文件关闭这样的操作。 read() 一次性将所有的内容都读取出来 readline() 每次只读取一行内容,如果要读取下一行可以再次执行 readlines() 会把所有行内容都读取出来,并且作为一个列表输出
csv:
csv的示例文件使用了来自阿里云:天池的NASA Facilities 美国宇航局设施:NASA设施名称和位置的数据集,该数据集的描述和下载链接在: https://tianchi.aliyun.com/dataset/dataDetail?dataId=88775 数据文件名称是:NASA_Facilities.csv 虽说后缀是csv,但他其实也就是一份纯文本文件,用with as 打开之后,按纯文本文件读取一点问题都没有,那么需要解决的就是如何存储,比如我们可以用一个list来存标题,再用两层list嵌套来存数据。
with open("NASA_Facilities.csv","r") as csvFile:
title = csvFile.readline().split(",")
print(title)
data = []
for line in csvFile.readlines() :
data.append(line.split(","))
print(len(data))
print(data[:3])
['Center', 'Center Search Status', 'Facility', 'FacilityURL', 'Occupied', 'Status', 'URL Link', 'Record Date', 'Last Update', 'Country', 'Location', 'City', 'State', 'Zipcode\n']
485
[['Stennis Space Center', 'Public', 'Test Stand A-2 #4122', '', '01/01/1964 12:00:00 AM', 'Inactive', 'http://rockettest.nasa.gov', '03/01/1996 12:00:00 AM', '04/06/2015 12:00:00 AM', 'US', '"39529-6000 (30.385948', ' -89.604486)"', 'Stennis Space Center', 'MS', '39529-6000\n'], ['Ames Research Center', 'Public', 'N229 - EXPER. AEROTHERMODYNAMIC FAC.: ELECTRIC ARC SHOCK TUBE FACILITY (PAPAC)', '', '01/01/1961 12:00:00 AM', 'Active', 'http://thermo-physics.arc.nasa.gov', '03/01/1996 12:00:00 AM', '06/13/2014 12:00:00 AM', 'US', '"94035 (37.41412', ' -122.052585)"', 'Moffett Field', 'CA', '94035\n'], ['Goddard Space Flight Center', 'Public', '"500 WSC: Antenna', ' 10m S-band"', '', '01/01/1977 12:00:00 AM', 'Active', '', '03/01/1996 12:00:00 AM', '08/15/2013 12:00:00 AM', 'US', '"20771 (38.99538', ' -76.853161)"', 'Greenbelt', 'MD', '20771\n']]
那当然,除了正常的文件读写以外,Python也支持通过csv模块来进行csv文件的读写。这里我们打印了第6列的前7行
csv.reader对文件生成了一个迭代器reader,当我们用for循环对迭代进行迭代时 row 指向了文件的每一行,它会自动地把每一行都已默认的分隔符,比如说逗号分隔成一个列表,那么这样我们就可以通过指定每一行中的列表的第几项来决定输出第几列文件,比如row[5]指的是第6列.那在循环里面,我们使用count来统计已经输出的函数.
当然,除此之外csv模块还提供了对文件写入的操作具体的使用方法,在csv.writer里
想要知道更多关于csv reader的或者csv writer的内容,可以使用help(csv.reader) help(csv.writer)
# 读取csv文件
import csv
with open('NASA_Facilities.csv', 'r') as csvFile:
reader = csv.reader(csvFile)
count = 1
for row in reader:
print(reader.line_num,row[5])
count += 1
if count > 7:# 用于限制输出次数
break
1 Status 2 Inactive 3 Active 4 Active 5 Active 6 Active 7 Active
json
把它保存为文件BJP2HBB.json 文件里面一共有26个车次和一些代码与车站的映射,那接下来我们把它转换成正常可以读的方式。
我注释把思路写的很清楚了,如果有什么函数或者语法上不懂的,就直接去百度搜就好了。
到我们人工去处理json文件的结构的时候,可能他整个文件都只写在一行,看起来非常的费劲,那这个时候我们可以用到一些线上的工具,比如https://www.json.cn/ 这是一个json格式在线解析和格式化的线上工具。可以比较有效的把那种一行的不太符合人类阅读习惯的文件去做一下转换。
import json
with open("BJP2HBB.json","r") as jsonFile: # 把文件打开
jsonFile = jsonFile.read()# 读入所有的内容
jsonFile = json.loads(jsonFile)# 使用json库把字符串转成可以识别的格式
trainNumList = jsonFile['data']['result']# 提取出车次信息
trainMap = jsonFile['data']['map']# 提取出站点代码跟站点的映射关系
for trainNum in trainNumList[:5]:# 循环处理所有车次信息.为了缩短输出,只处理前5项
print(trainNum.split('|')[3],end=" ")# 输出车次号码
startStationsTimes = trainNum.split('|')[6:9:2]# 提取出起始站点代码和发车时间 6和8
endStationsTimes = trainNum.split('|')[7:10:2]# 提取出到达站点和到达时间 7和9
for stationsTime in [startStationsTimes,endStationsTimes] :
print(trainMap[stationsTime[0]],end=" ")# 输出站点名称,把站点代码映射为站点名称
print(stationsTime[1],end=" ")# 输出发车或者到达时间
print()# 换行
Z157 北京 05:59 哈尔滨西 17:25 D29 北京 06:34 哈尔滨西 14:39 D29 北京 06:34 哈尔滨 14:53 G393 北京南 07:00 哈尔滨 14:10 G381 北京南 07:54 哈尔滨西 15:33
那么一般当把文件里面的数据或者是标签之类的都处理出来之后,就可以进行数据的计算和分析了。
xls&xlsx xls和xlsx是office独有的文件格式,它的文件的存储形式是二进制,所以里面的内容无法通过直接打开文件来读取,需要通过一些外部的包来进行中介,比如xlrd/xlwt/openpyxl 实际上是很不建议使用xls来进行数据文件的交换的,最大的问题在于它只支持16384列和1048576行。这个数据量看起来挺大但实际在处理大量数据时,很容易就会超出这个限制。
以上面这个样例文件入手,把总价计算出来。
import xlrd, xlwt
from xlutils.copy import copy
workbook = xlrd.open_workbook("xlsFiletest.xls")# 打开输入文件
worksheet = workbook.sheet_by_index(0)# 找到第1个工作表
price = worksheet.col_values(1)# 把单价读出来
print(price)
count = worksheet.col_values(2)# 把数量读出来
print(count)
workbook = copy(workbook)# 通过copy把只读改为可读写
worksheet = workbook.get_sheet(0)
print("总价")
for rowCount in range(1,len(price)):
totalPrice = round(float(price[rowCount])*float(count[rowCount]),2)# 计算总价
print(totalPrice,end = " ")# 从屏幕上打印价格
worksheet.write(rowCount,3,totalPrice)# 把价格写入工作表对应位置
workbook.save("xlsFileoutput.xls")# 保存文件
['单价', 1.2, 3.5, 5.2, 7.0, 4.0, 6.1, 4.0, 9.0] ['个数', 1.0, 5.0, 6.0, 3.0, 2.0, 5.0, 5.0, 9.0] 总价 1.2 17.5 31.2 21.0 8.0 30.5 20.0 81.0