CSV文件,也就是Comma-separated Value文件,用sublime打开是这样(数据下载见文末):
如果用excel打开是这样(千万别点保存,保存就有问题):
来看看怎么打开,如果安装了anaconda,我们先打开Jupyter Notebook,新建一个ipynb文件:
我们看完数据了,应该从哪里开始?当然是从python官方文档 开始!先搜下csv,找到
不少结果,csv是python一个模块,有不少方法。要用这个库,就要导入,但是csv不支持Unicode输入。稳妥起见,还是选择unicodecsv模块。
如果要打开文件,应该是open这个关键词吧,搜一下,结果看起来好复杂!抽取下,发现基本格式是open(name[, mode[, buffering]]),name是欲打开文件的名字,mode是打开方式(r是读,w是写,如果没有这个参数那默认是r),当然加上b也是极好的,意思就是Opens a file for reading only in binary format。
buffering这个参数是可选参数,暂时不管。
open(name[, mode[, buffering]])
Open a file, returning an object of the file type described in section File Objects. If the file cannot be opened, IOError is raised. When opening a file, it’s preferable to use open() instead of invoking the file constructor directly.
找到了官方文档的例子
import csv
with open('some.csv', 'rb') as f:
reader = csv.reader(f)
for row in reader:
print row
看起来可以直接用,我们试一试。
import unicodecsv
with open('enrollments.csv', 'rb') as f:
reader = unicodecsv.reader(f)
for row in reader:
enrollments.append(row)
enrollments[0]
输出结果是[u’account_key’,u’status’,u’join_date’,u’cancel_date’,u’days_to_cancel’,u’is_udacity’,u’is_canceled’],看起来像表头,我们再看看enrollments[1]是什么:
[u’448′, u’canceled’, u’2014-11-10′, u’2015-01-14′, u’65’, u’True’, u’True’]
还有enrollments[2]是什么
[u’448′, u’canceled’, u’2014-11-05′, u’2014-11-10′, u’5′, u’True’, u’True’]
原来是一行一行的读,是列表形式,不带表头的。如果我们想带表头怎么办?有一个方法,用DictReader,看看官方文档怎么说:
class csv.DictReader(csvfile, fieldnames=None, restkey=None, restval=None, dialect=’excel’, *args, **kwds)
Create an object which operates like a regular reader but maps the information read into a dict whose keys are given by the optional fieldnames parameter. The fieldnames parameter is a sequence whose elements are associated with the fields of the input data in order. These elements become the keys of the resulting dictionary.
好了,我们大概知道怎么写了。
简单解释一下代码意思,先整体看一下。
import unicodecsv
enrollments = []
f= open('enrollments.csv', 'rb')
reader = unicodecsv.DictReader(f)
for row in reader:
enrollments.append(row)
f.close()
enrollments[0]
然后一句一句解读。
import unicodecsv
#导入unicodecsv模块,其实导入csv也行,只不过unicodecsv能够处理更多格式的字体
enrollments = []
#创建一个名为enrollments的列表,其实下面的reader这个迭代器也能够迭代,但只能迭代一次,后面我们需要多次用到迭代,
#所以我们创建一个列表,可以多次迭代
f= open('enrollments.csv', 'rb')
reader = unicodecsv.DictReader(f)
#以只读方式打开enrollments.csv文件,写入到f文件句柄里
#以字典形式读取f文件句柄里的内容,写入到reader里,reader是一个迭代器(只能迭代一次)
for row in reader:
enrollments.append(row)
#开始for循环,使用append方法将文件的每一行添加到之前创建的enrollments列表里
f.close()
#关闭f文件句柄
enrollments[0]
#打印第一个元素
点击运行按钮,运行出现错误!报错为没有找到该文件,什么原因导致的呢?jupyter notebook工作路径导致的。需要将jupyter notebook工作路径和读取文件所在路径保持一致。
我们需要将其工作路径调整到和enrollments.csv文件同一个路径下,使用”cd d:anaconda“来改变notebook的工作路径,再次运行就可以了。
注意结果是一个字典,u’account_key’:u’448’这里的u表示unicode,本质上这里的448及所有的键值都是字符串类型。
我们可以简写这段代码,用‘with…as f’就可以省去f.close()这一句,即不需要再写关闭语句。
import unicodecsv
enrollments = []
with open('enrollments.csv', 'rb') as f:
reader = unicodecsv.DictReader(f)
for row in reader:
enrollments.append(row)
enrollments[0]
另外,可以由更简便的方法把迭代器变成列表,由最初的8行变成了5行,输出结果一样。看看官方文档
class list([iterable])
Return a list whose items are the same and in the same order as iterable‘s items. iterable may be either a sequence, a container that supports iteration, or an iterator object. If iterable is already a list, a copy is made and returned, similar to iterable[:]. For instance, list(‘abc’) returns [‘a’, ‘b’, ‘c’] and list( (1, 2, 3) ) returns [1, 2, 3]. If no argument is given, returns a new empty list, [].
那我们就试试,这样就不用新建空列表:
import unicodecsv
with open('enrollments.csv', 'rb') as f:
reader = unicodecsv.DictReader(f)
enrollments = list(reader)
enrollments[0]
如果需要读取多个文件,如果读取三个文件,就要把语句写3遍,后续debug也麻烦,这时候就需要考虑自己创建一个函数。
def read_csv(filename):
with open(filename, 'rb') as f:
reader = unicodecsv.DictReader(f)
return list(reader)
这样就能够读取不同的文件了。
enrollments = read_csv('enrollments.csv')
daily_engagement = read_csv('daily_engagement.csv')
project_submissions = read_csv('project_submissions.csv')