Python的数据分析包Pandas具备读写csv文件的功能,read_csv 实现读入csv文件,to_csv写入到csv文件。每个函数的参数非常多,可以用来解决平时实战时,很多棘手的问题,比如设置某些列为时间类型,当导入列含有重复列名称时,当我们想过滤掉某些列时,当想添加列名称时...
这篇专题我们结合官方文档,带你全面了解这些常用的参数,真正用透这2个函数。实际上,通过这2个函数的学习,我们不光能理解透这两个函数,顺便还可以了解更多Pandas的知识点,下面开始我们的专题之旅。
读入一个带分隔符的csv文件到DataFrame中,也支持遍历或文件分割为数据片(chunks).
下面是函数的原型:
read_csv(filepath_or_buffer, sep=',', delimiter=None, header='infer', names=None, index_col=None, usecols=None, squeeze=False, prefix=None, mangle_dupe_cols=True, dtype=None, engine=None, converters=None, true_values=None, false_values=None, skipinitialspace=False, skiprows=None, skipfooter=0, nrows=None, na_values=None, keep_default_na=True, na_filter=True, verbose=False, skip_blank_lines=True, parse_dates=False, infer_datetime_format=False, keep_date_col=False, date_parser=None, dayfirst=False, iterator=False, chunksize=None, compression='infer', thousands=None, decimal=b'.', lineterminator=None, quotechar='"', quoting=0, doublequote=True, escapechar=None, comment=None, encoding=None, dialect=None, tupleize_cols=None, error_bad_lines=True, warn_bad_lines=True, delim_whitespace=False, low_memory=True, memory_map=False, float_precision=None)
filepath_or_buffer: 数据输入路径,可以是文件路径,也可以是URL,或者实现read方法的任意对象。
sep: 数据文件的分隔符,默认为逗号。假如sep为None,python引擎会通过内置的 csv.Sniffer工具自动判断分隔符。
注意:如果分割字符长度大于1,且不是 '\s+'
, 启动python引擎解析。
举例: test.csv文件分割符为 '\t'
, 如果使用sep默认的逗号分隔符,读入后的数据混为一体。
In [4]: df = pd.read_csv('test.csv')
In [5]: df Out[5]: id\tname\tage0 1\t'gz'\t101 2\t'lh'\t12
此时,sep必须设置为 '\t'
,数据方可正确读入。再变换test.csv的分割符为两个空格,此时分隔符设置为 \s+
就可以正确读入。
In [7]: df = pd.read_csv('test.csv',sep='\s+') In [8]: df Out[8]: id name age0 1 'gz' 101 2 'lh' 12
In [9]: df['id'] Out[9]: 0 11 2Name: id, dtype: int64
delimiter: 分隔符的另一个名字,与sep相似
delim_whitespace: 0.18版本后新加参数,默认为False, 设置为True时,表示分割符为空白字符,可以是一个空格,两个,或 \t
等。
如下test.csv文件分隔符为两个空格时,设置delim_whitespace为True:
In [4]: df = pd.read_csv('test.csv',delim_whitespace=True)In [5]: df Out[5]: id name age0 1 'gz' 101 2 'lh' 12
In [6]: df['id'] Out[6]: 0 11 2Name: id, dtype: int64
header:设置导入数据框的列名称,默认为 'infer'
,注意它与 names
参数的微妙关系。
当names没有被赋值,header会被infer为0,即选取数据文件的第一行作为列名称; 当names被赋值,header没被赋值时会被infer为None
. 官方文档就介绍了这些,但是,如果它们都不被赋值,行为header会被infer为0;如果都赋值,就会实现两个参数的组合功能。
假如我们的数据文件只有如下两行:
1 'gz' 102 'lh' 12
分别看下这几种情况:
1) names没有被赋值,header也没赋值:
In [9]: df = pd.read_csv('test.csv',delim_whitespace=True)
In [10]: df Out[10]: 1 'gz' 100 2 'lh' 12
2) names没有赋值,header被赋值,此处有使用陷阱,切记: 数据域开始于行header设置值后一个
如下,因为我们的文件一共就只有两行,所以当header设置为1后,数据域始于index等于2处,超出数据范围,所以得到Empty DataFrame.
In [22]: df=pd.read_csv('test.csv',delim_whitespace=True,header=1)
In [23]: df Out[23]: Empty DataFrameColumns: [2, 'lh', 12]Index: []
3) names被赋值,header没有被赋值,常用的模式:
In [15]: df = pd.read_csv('test.csv',delim_whitespace=True,names=['id','name','a ...: ge'])
In [16]: df Out[16]: id name age0 1 'gz' 101 2 'lh' 12
4) names和header都被设置:
In [26]: df = pd.read_csv('test.csv',delim_whitespace=True,names=['id','name','a ...: ge'],header=0)
In [27]: df Out[27]: id name age0 2 'lh' 12
index_col 参数表示为使用哪个或哪些列作为index, 如下所示,数据文件还是只含有两行数据的test.csv,当我们设置index_col为id列时,就会生成一个index为id列的,columns只含有两列的数据框:
In [32]: df = pd.read_csv('test.csv',delim_whitespace=True,names=['id','name','a ...: ge'],index_col='id')
In [33]: df Out[33]: name ageid 1 'gz' 102 'lh' 12
当index_col为多个元素时,生成一个多索引数据框:
In [34]: df = pd.read_csv('test.csv',delim_whitespace=True,names=['id','name','a ...: ge'],index_col=['id','name'])
In [35]: df Out[35]: ageid name 1 'gz' 102 'lh' 12
usecols 参数用于选取数据文件的某些列到数据框中,如下所示,原数据文件,我们只想使用id和age两列,那么我们可以为usecols参数赋值为['id','age']:
In [36]: df = pd.read_csv('test.csv',delim_whitespace=True,names=['id','name','a ...: ge'],usecols=['id','age'])
In [37]: df Out[37]: id age0 1 101 2 12
squeeze 参数用于当读入的数据文件只有一列时,直接压缩为Series对象,默认为False, 如下当我们只需要导入id列时,如果不设置,返回的也是DataFrame实例:
In [41]: df = pd.read_csv('test.csv',delim_whitespace=True,names=['id','name','a ...: ge'],usecols=['id'])
In [42]: df Out[42]: id0 11 2
In [43]: type(df) Out[43]: pandas.core.frame.DataFrame
但是,如果我们设置了squeeze为True后,返回的就是Series对象,如下:
In [38]: df = pd.read_csv('test.csv',delim_whitespace=True,names=['id','name','a ...: ge'],usecols=['id'],squeeze=True)
In [39]: df Out[39]: 0 11 2Name: id, dtype: int64
In [40]: type(df) Out[40]: pandas.core.series.Series
现实中的数据错综复杂,如果导入的数据含有相同名称的列,我们该怎么办?
为了高效地模拟重复列,我们使用极简的数据重现,还是原来的test.csv文件,我们故意将数据改造为如下:
id id age1 'gz' 102 'lh' 12
此时导入数据后,得到如下数据框:
In [44]: df = pd.read_csv('test.csv',delim_whitespace=True)
In [45]: df Out[45]: id id.1 age0 1 'gz' 101 2 'lh' 12
可以看到某个列名称自动变为id.1,控制这个行为的为参数 mangledupecols, 它默认为True. 如果设置为False,我们看看会发生什么,会抛不支持的异常:
ValueError: Setting mangle_dupe_cols=False is not supported yet
但是官方文档中说明是这样的:Passing in False will cause data to be overwritten if there are duplicate names in the columns. 此处可能是Pandas包的问题,一回看看。
还有一个 prefix 参数比较有意思,当我们导入的数据没有header时,我们把此参数设置为my时,列自动变为my0, my1, my2,... 如下:
In [55]: df = pd.read_csv('test.csv',delim_whitespace=True,prefix='my',header=No ...: ne)
In [56]: df Out[56]: my0 my1 my20 id id age1 1 'gz' 102 2 'lh' 12
read_csv 的其他参数还包括如下:
接下来,还会介绍to_csv背后的故事。
一个函数,就是一场故事。
本文分享自 程序员郭震zhenguo 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!