CSV (Comma Separated Values)作为一种逗号分隔型值的纯文本格式文件,在实际应 用中经常用到, 如数据库数据的导人导出、数据分析中记录的存储等因此很多语言都提供 了对CSV文件处理的模块, Python也不例外,其模块csv提供了一系列与CSV处理相关的 API。
我们先来看一下其中几个常见的API:
reader(csvfile[,dia]ect='excel'][, fmtparam])
,主要用于 CSV 文件的读取,返回一个 reader对象用于在CSV文件内容上进行行迭代。
参数csvfile,需要是支持迭代(Iterator)的对象,通常对文件(file)对象或者列表(list) 对象都是适用的,并且每次调用next()
方法的返回值是字符串(string);参数dialect的默认 值为excel,与excel兼容;frntparam是一系列参数列表,主要用于需要覆盖默认的Dialect 设晋.的情形当dialect设置为excel的时候,默认Dialect的值如下:
csv.writer(csvfile, dialect='excel', **fmtparams)
,用于写人 CSV 文件。参数同上。来看一个使用例子。
csv.DictReader(csvfile,fieldnames=None,restkey=None,restval==None, dialect='excel', *args,**kwds)
,同reader()
方法类似,不同的是将读人的信息映射到一个字典中去,其中字 典的key由fieldnames指定,该值省略的话将使用CSV文件第一行的数据作为key值。如果 读入行的字段的个数大于filednames中指定的个数,多余的字段名将会存放在restkey中,而 restval主要用于当读取行的域的个数小于fieldnames的时候,它的值将会被用作剩下的key 对应的值。csv.DictWriter(csvfile, fieldnames , restval='', extrasaction='raise',dialeet='excel',*args, **kwds)
,用T支持字典的写入。
CSV模块使非常简单,基本可以满足大部分需求。但你有没有恩考过这个问题:有些 应用中需要解析和处理的CSV文件可能有上百MB甚至几个GB,这种情况下CSV模块是否 能够应付呢?先来做个实验,临时创建一个1GB的CSV文件并将其加载到内存中.看看会 有什么问题发生。
上面的例子中当企图读人这个CSV文件的时候抛出了 MemoryError异常a这是为什 么?因为csv模块对于大型CSV文件的处理无能为力。这种情况下就需要考虑其他解决方案 了,pandas模块便是较好的选择。
Pandas即Python Data Analysis Library,是为了解决数据分析而创建的第三方工具,它 不仅提供了丰富的数据模型,而且支持多种文件格式处理,包括CSV、HDF5、HTML等, 能够提供高效的大型数据处理。其支持的两种数据结构——Series和DateFrame——是数据处 理的基础。下面先来介绍这两种数据结构。
- Series:它是一种类似数组的带索引的一维数据结构,支持的类型与NumPy兼容。如 果不指定索引,默认为0到N-1通过
obj.values()
和obj.index()
可以分别获取值和索引。当给Series传递一个字典的时候,Series的索引将根据字典中的键棑序。如果传 人字典的时候同时重新指定了 index参数,当index与字典中的键不匹配的时候,会 出现时数据丢失的情况,标记为NaN。
在pandas中用函数isnull()
和notnull()
来检测数据是否丢失。
import pandas
obj1=pandas.Series([1,'a',(1,2),3],index=['a','b','c','d'])
obj1
a 1 b a c (1, 2) d 3 dtype: object
obj2=pandas.Series({"Book":"Python","Author":"Dan","ISBN":"011334","Price":25},index
=["book","Author","ISBM","Price"])
obj2
book NaN Author Dan ISBM NaN Price 25 dtype: object
- DataFrame:类似于电子表格,其数据为排好序的数据列的集合,每一列都可以是 不同的数据类型,它类似于一个二维数据结构.支持行和列的索引。和Series — 样,索引会自动分配并且能根据指定的列进行排序9使用最多的方式是通过一个长 度相等的列表的字典来构建。构建一个DataFrame最常用的方式是用一个相等长度 列表的字典或NumPy数组。DataFrame也叶以通过columns指定序列的顺序进行 排序。
data={'orderDate':['1-6-10','1-23-10','2-9-10','3-23-20','3-19-10'],
'region':['east','cesdf','asdcve','egedsa','east'],
'Rep':['jones','kivell','aasdfj','gill','sorvion']}
pandas.DataFrame(data,columns=['orderdata','region','rep'])
orderdata | region | rep | |
---|---|---|---|
0 | NaN | east | NaN |
1 | NaN | cesdf | NaN |
2 | NaN | asdcve | NaN |
3 | NaN | egedsa | NaN |
4 | NaN | east | NaN |
Pandas中处理CSV文件的函数主要为read_csv()
和to_csv()
这两个,其中read_csv()
读取CSV文件的内容并返回DataFmme, to_csv()
则是其逆过程。两个函数都支持多个参数, 由于其参数众多且过于复杂,本节不对各个参数一一介绍,仅选取几个常见的情形结合具体 例子介绍。下面举例说明
1)指定读取部分列和文件的行数。具体的实现代码如下:
df=pandas.read_csv("sampledata.csv",nrows=9,usecols=['orderdata','item','total'])
df
orderdata | item | total | |
---|---|---|---|
0 | 1-6-10 | pencil | NaN |
1 | 2-6-10 | pencil | NaN |
2 | 2-9-10 | pencil | NaN |
3 | 3-16-10 | pencil | NaN |
4 | 3-26-10 | pencil | NaN |
5 | 5-36-10 | pencil | NaN |
6 | 5-56-10 | pencil | NaN |
7 | 6-66-10 | pencil | NaN |
方法read_csv()的参数nrows指定读取文件的行数,usecols指定所要读取的列的列名, 如果没有列名,可直接使用索引0、1、...、n-1。上述两个参数对大文件处理非常有用,可 以避免读人整个文件而只选取所需要部分进行读取。
2)设置CSV文件与excel兼容。dialect参数可以是string也可以是csv.Dialect的实例。 如果将图4-2所示的文件格式改为使用“丨”分隔符,则需要设置dialect相关的参数。error_badlines设置为False,当记录不符合要求的时候,如记录所包含的列数与文件列设置不相 等时可以直接忽略这些列。下面的代码用于设置CSV文件与eXCd兼容,其中分隔符为"|", 而error_bad_lines=False会直接忽略不符合要求的记录。
import csv
dia=csv.excel()
dia.delimiter="|"
pandas.read_csv("sampledata.csv")
orderdata | region | rep | item | units | unit | cost | total | |
---|---|---|---|---|---|---|---|---|
0 | 1-6-10 | east | jones | pencil | 95 | 1.99 | 189.05 | NaN |
1 | 2-6-10 | easdfast | jones | pencil | 95 | 1.99 | 189.05 | NaN |
2 | 2-9-10 | edfast | jones | pencil | 95 | 1.99 | 189.05 | NaN |
3 | 3-16-10 | east | jones | pencil | 95 | 1.99 | 189.05 | NaN |
4 | 3-26-10 | central | jones | pencil | 95 | 1.99 | 189.05 | NaN |
5 | 5-36-10 | central | jones | pencil | 95 | 1.99 | 189.05 | NaN |
6 | 5-56-10 | central | jones | pencil | 95 | 1.99 | 189.05 | NaN |
7 | 6-66-10 | east | jones | pencil | 95 | 1.99 | 189.05 | NaN |
pandas.read_csv("sampledata.csv",dialect=dia,error_bad_lines=False)
/tmp/ipykernel_20649/2299398768.py:1: FutureWarning: The error_bad_lines argument has been deprecated and will be removed in a future version. Use on_bad_lines in the future. pandas.read_csv("sampledata.csv",dialect=dia,error_bad_lines=False)
orderdata,region,rep,item,units,unit,cost,total | |
---|---|
0 | 1-6-10,east,jones,pencil,95,1.99,189.05 |
1 | 2-6-10,easdfast,jones,pencil,95,1.99,189.05 |
2 | 2-9-10,edfast,jones,pencil,95,1.99,189.05 |
3 | 3-16-10,east,jones,pencil,95,1.99,189.05 |
4 | 3-26-10,central,jones,pencil,95,1.99,189.05 |
5 | 5-36-10,central,jones,pencil,95,1.99,189.05 |
6 | 5-56-10,central,jones,pencil,95,1.99,189.05 |
7 | 6-66-10,east,jones,pencil,95,1.99,189.05 |
3)对文件进行分块处理并返回一个可迭代的对象。分块处理可以避免将所有的文件载人 内存,仅在使用的时候读人所需内容。参数chimksize设置分块的文件行数,10表示每一块 包含10个记录。将参数iterator设置为True时,返回值为TextFileReader,它是一个可迭代对象,来看下面的例子,当chunk5ize=10、iterator=True时,每次输出为包含10个记录的块。
reader=pandas.read_table("sampledata.csv",chunksize=10,iterator=True)
reader
<pandas.io.parsers.readers.TextFileReader at 0x7f0200a7b650>
iter(reader).next()# 将 TextFileReader 转换为送代器并调用 next 方法
0 l-6-10rEast# Jones,Pencilr 95r 1.99 • 189.05
1 l-23-10#CentralrKivell^Binder,50# 19.99 , 999.50
2 2-9-10#CentralrJardine,Pencilr36r 4.99 , 179.64
3 2-2-10rCentral,Gill#Pen,27# 19.99 , 539.73
4 3-15-10,WestrSorvinofPencilf56r 2.99 , 167.44
5 4-l-10rEast,JonesfBinderr60, 4,99 i 299.40
6 4-18-10,Central^ Andrews, Pencilf 75, K99 , 149.2S
7 5-5-10,CentraliJardine,Pencilr90, 4^99 , 449.10
8 5-22-10,West,Thompson,Pencil, 32, 1.99 , 63.68
9 6-8-10,East,Jones,Binderf 60, 8*99 j 539.40
4)当文件格式相似的时候,支持多个文件合并处理。以下例子用于将3个格式相同的 文件进行合并处理。
import os
filelst=os.listdir('test')
print(filelst)
['test1.csv', 'test2.csv']
os.chdir("test")
dfs=[pandas.read_csv(f) for f in filelst]
total_df=pandas.concat(dfs)
total_df
了解完pandas后,读者可以自行实验一下使用pandas处理前面生成的1GB的文件,看 着还会不会抛出MemoryError异常
在处理CSV文件上,特别是大型CSV文件,pandas不仅能够做到与csv模块兼容,更 重要的是其CSV文件以DataFirame的格式返回,pandas对这种数据结构提供了非常丰富的 处理方法,同时pandas支持文件的分块和合并处理,非常灵活,由于其底层很多算法采用 Cython实现运行速度较快。实际上pandas在专业的数据处理与分析领域,如金融等行业已经得到广泛的应用。