5.3 CSV FILES
在平常的分析中,会经常遇到csv格式的文件,csv代表的是Comma Separated Values,即文件内的分隔符是逗号。csv文件的另一个特点是常常一行就代表一个record,即代表一个样本或者一个单元的数据。基本所有的电子表格都能够整理为这种格式,所以这种固定分隔符的格式非常流行。
这一节以这个B1.csv文件作为例子讲一下python中csv文件的处理:
1 2 3 4 5 6 7 |
MarkerID,LenAmp,MotifAmpForSeq TKO001,119,AG(12) TKO002,255,TC(16) TKO003,121,AG(5) TKO004,220,AG(9) TKO005,238,TC(17) |
这个文件第一行相当于列名,之后的所有行都是对应顺序的数据或者信息。
读取:
1 2 3 4 5 6 7 8 |
1. total_len = 0 2. with open('C:/Users/pengxi/Desktop/test.csv','r') as fh: 3. next(fh) 4. for n, line in enumerate(fh): 5. data = line.split(',') 6. total_len += int(data[1]) 7. print(total_len/n) |
enumerate()可以将可遍历的数据对象(比如list,tuple或者str)同时标出数据和索引。
举个例子:
1 2 3 4 5 6 |
>>>seasons = ['Spring', 'Summer', 'Fall', 'Winter'] >>> list(enumerate(seasons)) [(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')] >>> list(enumerate(seasons, start=1)) # 下标从 1 开始 [(1, 'Spring'), (2, 'Summer'), (3, 'Fall'), (4, 'Winter')] |
split()函数可以把每行按指定的字符分割,有点类似于excel里的分列功能。在csv里可以用逗号,在tabular里就用tab(’\t’)等等。
Python也有专门的csv模块来处理csv文件。
1 2 3 4 5 6 7 8 |
1. import csv 2. total_len=0 3. lines = csv.reader(open('C:/Users/pengxi/Desktop/test.csv', 'r')) 4. next(lines) 5. for n, line in enumerate(lines): 6. total_len += int(line[1]) 7. print(total_len/n) |
这段代码和前面那段功能是一样的,csv模块能够直接按照csv的格式习惯读取每一行的内容了,省去了使用split()。
在csv模块下可以直接通过二维索引来指向某一元素。还是以上面的lines作为例子:
1 2 3 4 5 6 7 8 9 10 11 12 |
1. import csv 2. total_len=0 3. lines = csv.reader(open('C:/Users/pengxi/Desktop/test.csv', 'r')) 4. ''' 5. next(lines) 6. for n, line in enumerate(lines): 7. total_len += int(line[1]) 8. print(total_len/n) 9. ''' 10. data = list(lines) 11. print(data[0][2]) |
返回的值就是第1行(index是0)第3列(index是2)的元素MotifAmpForSeq,所以这个二维数组的索引规则是先行再列。
csv.reader()里的delimiter参数可以用来改变分隔符,上面用的是默认值,也就是逗号,也可以改成其他的:
1 |
rows = csv.reader(open(’/etc/passwd’), delimiter=’:’) |
有些文件我们应该明确CSV dialect,也就是我们希望怎么使用这个csv文件。这很重要,因为不是所有的csv文件结构都一样,它并不是一个formal standard,所以很有可能有很多变化形式。这些细微的区别很有可能最终导致报错!举个例子,有些情况下数据之间有引号隔开了,另外一些则只有文本会被引号括起来。对于excel生成的csv文件的,csv模块有专门的excel dialect:
1 |
rows = csv.reader(open(’data.csv’), dialect=’excel’) |
如果我们不确定应该用那种dialect,可以用
1 |
Sniffer() |
来测试一下:
1 2 3 |
dialect = csv.Sniffer().sniff(open(’data.csv’).read()) rows = csv.reader(open(’data.csv’), dialect=dialect) |
作者附上了csv模块的说明文档链接,暗示不会的自己查~
To find out more about it, I recommend the module documentation at https://docs.python.org/3/library/csv.html and the PEP-305 (https://www.python.org/dev/peps/pep-0305/), an old but still valid document.
csv是个非常容易上手处理的文件格式,不过它不能表示具有层级关系的数据,能够干这件事的还有JSON和XML格式文件,这本书后面会讲,读到了再记笔记。
csv模块可以让我们用python处理excel数据,前提是先把excel文件转化为csv文件。如果不想绕这个路,书里介绍了xlrd这个模块。另外对于写入excel文件,也对应介绍了xlwt这个模块。其实我今天用python做一些之前用R代码写过的任务的时候,发现pandas其实是个很好用的包。之后有机会系统学习一下pandas和numpy,是数据处理的神器。
这篇笔记参考了:
https://www.runoob.com/python/python-func-enumerate.html
https://www.runoob.com/python/python-func-next.html
分别是菜鸟教程对于enumerate()和next()两个函数的解释。