Pandas读取CSV

Pandas读取CSV

语法

基本语法如下,同时可以把pandas模块导入后设置别名为pd:

pd.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, 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, escapechar=None, comment=None, encoding=None, dialect=None,
            tupleize_cols=False, error_bad_lines=True, warn_bad_lines=True, skipfooter=0,
            skip_footer=0, doublequote=True, delim_whitespace=False, as_recarray=False,
            compact_ints=False, use_unsigned=False, low_memory=True, buffer_lines=None,
            memory_map=False, float_precision=None)

一般情况下,会将读取到的数据返回一个DataFrame,当然按照参数的要求会返回指定的类型。

数据内容

filepath_or_buffer为第一个参数,没有默认值,不能为空,根据python的语法,第一个参数可以不写参数名。可以传文件路径:

#支持文件路径或者文件缓冲对象
#本地的相对路径
pd.read_csv('data/data.csv') #注意目录的层级关系
pd.read_csv('data.csv') #使用在代码和文件在同一个目录下
pd.read_csv('data/my/my.data') #CSV的扩展名字不一定就是.csv

#本地绝对路径
pd.read_csv('/usr/gairuo/data/data.csv')

#使用URL
pd.read_csv('https://www.gairuo.com/file/data/dataset/GDP-China.csv')

这里要注意的是路径的使用,在Mac和Windows上的路径写法是不一样的,上面实例使用的是Mac中的写法,Windows中的绝对路径和相对路径需要分别换成类似'data\data.csv'和'E:\data\data.csv'的格式!!

另外,路径尽量不要用中文,容易报错,所以在存放数据文件的目录尽量要用英文名字。

可以传输字符串,CSV中的数据字符以字符串形式直接传入:

from io import StringIO
data = ('col1,col2,col3\n'
       'a,b,1\n'
       'a,b,2\n'
       'c,d,3')
pd.read_csv(StringIO(data))
pd.read_csv(StringIO(data),dtype=object)

也可以传入字节数据:

from io import BytesIO
data = (b'word,length\n'
       b'Tr\xc3\xa4umen,7\n'
       b'Gr\xc3\xbc\xc3\x9fe,5')
pd.read_csv(BytesIO(data))

分隔符

sep参数是字符型的,代表每行数据内容的分割符号,默认是逗号,另外常见的还有制表符(\t)、空格等。根据数据的实际情况传参。

#数据分隔符默认是逗号,可以指定其他符号
pd.read_csv(data,sep='\t') #制表符分隔tab
pd.read_table(data) #read_table默认是制表符分隔tab
pd.read_csv(data,sep='|') #制表符分隔tab
pd.read_csv(data,sep="(?<!a)\|(?!1)",engine='python') #使用正则表达式

pd.read_csv还提供了一个参数名为delimiter的定界符,这是一个备选分隔符,是sep的别名,和sep的效果是一样的,如果指定该参数,sep就会失效。

表头

header参数支持整型和由整形组成的列表,指定第几行表头,默认会自动推断把第一行作为表头。

pd.read_csv(data,header=0) #第一行作为表头
pd.read_csv(data,header=None) #没有表头
pd.read_csv(data,header=[0,1,3])#多层索引MultiIndex

需要注意的是:如果skip_blank_lines=True,header参数将忽略空行和注释行,因此header=0表示第一行数据而非文件的第一行!!!

列名

names用来指定列的名称,它是一个类似列表的序列,与数据一一对应。如果文件不包含列名,那么就设置header=None,列名列表不允许由重复值。

pd.read_csv(data,names=['列1','列2'])#指定列名列表
pd.read_csv(data,names=['列1','列2'],header=None)

索引

index_col用来指定索引列,可以是行索引的列编号或者列名,如果给定一个序列,则有多个行索引。Pandas不会自动将第一列作为索引,不指定时会自动使用以0开始的自然索引。

#支持int、str、int序列、str序列、False,默认为None
pd.read_csv(data,index_col=False) #不再使用首列作为索引
pd.read_csv(data,index_col='年份') #第几列是索引
pd.read_csv(data,index_col=['a','b']) #多个索引
pd.read_csv(data,index_col=[0,3])#按列索引指定多个索引

使用部分列

如果使用数据的部分列,就可以用usecols指定,这样可以减少内存的消耗并提高加载速度。

#支持类似列表的序列和可调用对象
#读取部分列
pd.read_csv(data,usecols=[0,4,3]) #按索引读取指定列,和顺序没有关系
pd.read_csv(data,usecols=['列1','列5']) #按列名(列名必须是存在的!)
pd.read_csv(data,usecols=['列1','列5'])[['列5','列1']]

#以下用callable方式可以巧妙指定顺序,in后面的是我们要的顺序
pd.read_csv(data,usecols=lambda x:x.upper() in ['COL3','COL1'])

返回序列

将squeeze设置为True,如果文件只包含一列,则返回一个Series,如果有多列,则还是返回DataFrame。

#布尔型,默认为False
#下例只取一列,会返回一个Series
pd.read_csv(data,usecols=[0],squeeze=True)
#有两列则还是DataFrame
pd.read_csv(data,usecols=[0,2],squeeze=True)

表头前缀

如果原始数据没有列名,可以指定一个前缀加序数的名称,如n0、n1,通过prefix参数指定前缀。

#格式为字符型str
#表头为c_0、c_2
pd.read_csv(data,prefix='c_',header=None)

处理重复列名

如果该参数为True,当列名有重复时,解析列名将变为X,X.1, ...,X.N,而不是X, ..., X。

如果该参数为False,那么当列名中有重复时,前列将会被后列覆盖!

#布尔型,默认为True
data = 'a,b,a\n0,1,2\n3,4,5'
pd.read_csv(StringIO(data),mangle_dupe_cols=True)
#表头为a b a.1
#False会报ValueError错误

数据类型

dtype可以指定各数据列的数据类型。

# 传入类型名称,或者以列名为键、以指定类型为值的字典
pd.read_csv(data,dtype=np.float64)#所有数据均为此数据类型
pd.read_csv(data,dtype={'c1':np.float64,'c2':str})#指定字段的类型
pd.read_csv(data,type=[datatime,datatime,str,float])#依次指定

引擎

使用的分析引擎可以选择C或Python。C语言的速度最快,Python语言的功能最为完善,一般情况下,不需要另行指定。

# 格式为engine=None,其中可选值有{'c','python'}
pd.read_csv(data,engine='c')

列数据处理

使用converters参数对列的数据进行转换,参数中指定列名与针对此列的处理函数,最终以字典的形式传入,字典的键可以时列名或者列的序号。

#字典的格式,默认为None
data = 'x,y\na,1\nb,2'
def foo(p):
    return p+'s'
#x应用函数,y使用lambda
pd.read_csv(StringIO(data),converters={'x':foo,'y':lambda x:x*3})
#使用列索引
pd.read_csv(StringIO(data),converters={0:foo,1:lambda x:x*3})

真假值转换

使用true_values和false_value将指定的文本内容转换为True或False,可以用列表指定多个值。

#列表,默认为None
data=('a,b,c\n1,Yes,2\n3,No,4')
pd.read_csv(StringIO(data),true_values=['Yes'],false_values=['No'])

跳过指定行

如下跳过需要忽略的行数或需要忽略的行号列表(从0开始):

#类似列表的序列或可调用对象
#跳过前三行
pd.read_csv(data,skiprows=2)
pd.read_csv(data,skiprows=range(2))
#跳过指定行
pd.read_csv(data,skiprows=[24,234,141])
pd.read_csv(data,skiprows=np.array([2,6,11]))
#隔行跳过
pd.read_csv(data,skiprows=lambda x:x%2!=0)

尾部跳过,从文件尾部开始忽略,C引擎是不支持的!!

# int类型,默认为0
pd.read_csv(filename,skipfooter=1) #最后一行不加载

skip_blank_lines指定是否跳过空行,如果为True,则跳过空行,否则数据记为NaN。

#布尔型,默认为True
#不跳过空行
pd.read_csv(data,skip_blank_lines=False)

如果skip_blank_lines=True,header参数将忽略空行和注释行,因此header=0表示第一行数据而非文件的第一行!!

读取指定行

nrows参数用于指定需要读取的行数,从文件第一行算起,经常用于较大的数据,先取部分进行代码编写。

# int类型,默认为None
pd.read_csv(data,nrows=1000)

空值替换

na_values参数的值是一组用于替换NA/NaN的值。如果传参,需要指定特定列的空值。以下值默认会被认定为空值:

['-1.#IND','1.#QNAN','1.#IND','-1.#QNAN',
'#N/A N/A','#N/A','N/A','n/a','NA',
'#NA','NULL','null','NaN','-NaN',
'nan','-nan','']

使用na_values时需要关注下面keep_default_na的配合使用和影响:

#可传入标量、字符串、类似列表序列和字典,默认为None
#5和5.0会被认为是NaN
pd.read_csv(data,na_values=[5])
#?会被认为是NaN
pd.read_csv(data,na_values='?')
#空值为NaN
pd.read_csv(data,keep_default_na=False,na_values=[""])
#字符NA和字符0会被认为是NaN
pd.read_csv(data,keep_default_na=False,na_values=["NA","0"])
#Nope会被认为是NaN
pd.read_csv(data,na_values=["Nope"])
#a、b、c均被认为是NaN,等于na_values=['a','b','c']
pd.read_csv(data,na_values='abc')
#指定列的指定值会被认为是NaN
pd.read_csv(data,na_values={'c':3,1:[2,5]})

保留默认空值

分析数据时是否包含有默认空值NaN,是否自动识别。

如果指定na_values参数,并且keep_default_na=False,那么默认的NaNcy将被覆盖,否则添加。

keep_default_na na_values 逻辑
TRUE 指定 na_values的配置附加处理
TRUE 未指定 自动识别
FALSE 指定 使用na_values的配置
FALSE 未指定 不做处理

如果na_filter为False(默认是True),那么keep_default_na和na_values参数都无效!!

#布尔型,默认为True
#不自动识别空值
pd.read_csv(data,keep_default_na=False)

na_filter是否检查丢失值。对于大文件来说,数据集中没有空值,设定na_filter=False可以提升读取速度。

#布尔型,默认为True
pd.read_csv(data,na_filter=False)#不检查!

日期时间解析

日期时间解析器参数data_parser用于解析日期的函数,默认使用dateutil.parser.parser来做转换。如果为某些或所有列启用了parse_dates,并且datetime字符串的格式都相同,则通过设置infer_datetime_format=True,可以大大提高解析速度,pandas将尝试推断datetime字符串的格式,然后使用更快的方法解析字符串,从而将解析速度提高5~10倍。如果无法对整列做出正确的推断解析,Pandas将返回到正常的解析模式。

下面是一些可以自动推断的日期时间字符串示例,它们都表示2020年12月30日00:00:00:

  • "20201230"
  • "2020/12/30"
  • "20201230 00:00:00"
  • "12/30/2020 00:00:00"
  • "30/Dec/2020 00:00:00"
  • "30/December/2020 00:00:00"
#解析时间的函数名,默认为None
#解析时间解析库,默认是dateutil.parser.parser
data_parser = pd.io.date_converters.parse_date_time
date_parser = lambda x :pd.to_datetime(x,utc=True,format='%d%b%Y')
date_parser = lambda d :pd.datetime.strptime(d,'%d%b%Y')
#使用
pd.read_csv(data,parse_dates=['年份'],date_parser=date_parser)

parse_dates参数用于对时间日期进行解析

#布尔值、整型组成的列表、列表组成的列表或字典,默认为False
pd.read_csv(data,parse_dates=True) #自动解析日期时间格式
pd.read_csv(data,parse_dates=['年份']) #指定日期时间字段进行解析
#将第1、4列合并解析成名为“时间”的时间类型列
pd.read_csv(data,parse_dates={'时间':[1,4]})

如果infer_datetime_format被设定为True并且parse_dates可用,那么Pandas将尝试转换为日期类型。

#布尔型,默认为False
pd.read_csv(data,parse_dates=True,infer_datetime_format=True)

如果用上文中的parse_dates参数将多列合并并解析成一个时间列,设置keep_date_col的值为True时,会保留这些原有的时间组成列;如果设置为False,则不保留这些列。

#布尔型,默认为False
pd.read_csv(data,parse_dates=[[1,2],[1,3]],keep_date_col=True)

对于DD/MM格式的日期类型,如日期2020-01-06,如果dayfirst=True,则会转换成2020-06-01。

#布尔型,默认为False
pd.read_csv(data,dayfirst=True,parse_dates=[0])

cache_dates如果为True,则使用唯一的转换日期缓存在应用datetime转换。解析重复的日期字符串,尤其时带有时区偏移的日期字符串时,可能会大大提高速度。

#布尔型,默认为True
pd.read_csv(data,cache_dates=False)

文件处理

以下是一些对读取文件对象的处理方法。iterator参数如果设置为True,则返回一个TextFileReader对象,并可以对它进行迭代,以便逐块处理文件。

#布尔型,默认为False
pd.read_csv(data,iterator=True)

chunksize指定文件块的大小,分块处理大型CSV文件。

#整型,默认为None
pd.read_csv(data,chunksize=100000)
#分块处理大文件
df_iterator=pd.read_csv(file,chunksize=50000)
def process_dataframe(df):
    pass
	return processed_df

for index,df_tmp in enumerate(df_iterator):
    df_processed=process_dataframe(df_tmp)
    if index > 0:
    	df_processed.to_csv(path)
    else:
        df_processed.to_csv(path,mode='a',header=False)

compression(压缩格式)用于对磁盘数据进行即时解压缩。如果为“infer”,且filepath_or_buffer是以.gz、.bz2、.zip或.xz结尾的字符串,则使用gzip、bz2、zip或xz,否则不进行解压缩。如果使用zip,则ZIP文件必须仅包含一个要读取的数据文件。设置为None将不进行解压缩。

#可选的有'infer'、'gzip'、'zip'、'xz'和None,默认为'infer'
pd.read_csv('sample.tar.gz',compression='gzip')

encoding(编码)指定字符集类型,通常指定为'utf-8'。

#字符型,默认为None
pd.read_csv('gairuo.csv',encoding='utf8')
pd.read_csv("gairuo.csv",encoding="gb2312") #常见中文

符号

以下是对文件中的一些数据符号进行的特殊识别处理。如下设置千分位分隔符thousands:

# 字符型,默认为None
pd.read_csv('test.csv',thousands=',')#逗号分隔

小数点decimal,识别为小数点的字符。

# 字符串,默认为‘.’
pd.read_csv(data,decimal=',')

行结束符lineterminator,将文件分成几行的字符,仅对C解析器有效。

#长度为1的字符串,默认为None
data='a,b,c~1,2,3~4,5,6'
pd.read_csv(StringIO(data),lineterminator='~')

引号quotechar,用于表示引用数据的开始和结束的字符。引用的项目可以包含定界符,它将被忽略。

#长度为1的字符串
pd.read_csv(file,quotechar='"')

在csv模块中,数据可能会用引号等字符包裹起来,quoting参数用来控制识别字段的引号模式,它可以是Python csv模块中的csv.QUOTE_*常量,也可以传入对应的数字。各个传入值的意义如下。

  • 0或csv.QUOTE_MINIMAL:仅特殊字段有引号。
  • 1或csv.QUOTE_ALL:所有字段都有引号。
  • 2或csv.QUOTE_NONNUMERIC:所有非数字字段都有引号。
  • 3或csv.QUOTE_NONE:所有字段都没有引号。

如果使用csv模块,则需要事先引入csv模块。

#整形或者csv.QUOTE_*实例,默认为0
import csv
pd.read_csv('input_file.csv',quoting=csv.QUOTE_NONE)

双引号doublequote,当单引号已经被定义,并且quoting参数不是QUOTE_NONE的时候,使用双引号表示将引号内的元素作为一个元素使用。

# 布尔值,默认为True
import csv
pd.read_csv('data.csv',quotechar='"',doublequote=True,quoting=csv.QUOTE_NONNUMERIC)

escapechar可以传入一个转义符,用于过滤数据中的该转入符。比如,如果一行用双引号包裹着的数据中有换行符,用以下代码可以过滤其中的换行符。

# 长度为1的转义字符串,默认为None
pd.read_csv(StringIO(data),escapechar='\n',encoding='utf-8')

注释标识comment,指示不应分析行的部分。如果在一行的开头找到该标识,则将完全忽略该行。此参数必须是单个字符。像空行一样(只要skip_blank_lines = True),注释的行将被参数header忽略,而不是被skiprows忽略。例如,如果comment ='#',则解析header=0的'#empty \ na,b,c \n1,2,3'会将'a,b,c'视为header。

# 字符串,默认为None
s = '# notes\na,b,c\n# more notes\n1,2,3'
pd.read_csv(StringIO(s),sep=',',comment='#',skiprows=1)

空格分隔符delim_whitespace,指定是否将空格(例如''或'\t')用作分隔符,等效于设置sep ='\s+'。如果此选项设置为True,则不应该为delimiter参数传递任何内容。

# 布尔型,默认为False
pd.read_csv(StringIO(data),delim_whitespace=False)
posted @ 2022-06-16 11:30  霜鱼CC  阅读(50)  评论(0)    收藏  举报