您现在的位置是:网站首页> 编程资料编程资料

pandas实现数据读取&清洗&分析的项目实践_python_

2023-05-26 328人已围观

简介 pandas实现数据读取&清洗&分析的项目实践_python_

近期因工作需要,需对几十万条商品和订单数据进行初步的数据分析,本来尝试过用Excel,但是数据量一旦超过10万条,Excel和电脑的性能瓶颈就捉襟见肘了,为了后续遇到类似问题提升处理效率,抽空系统性的研究学习了pandas这个库,初步上手之后,感觉以后再处理千万级的数据量的时候,也会游刃有余了,话不多讲,直接进入正题。

本文主要沿着在日常使用pandas处理数据时的步骤,讲解pandas对应的知识点和常见操作,分析工具使用jupyter-notebook,强烈推荐。

本文假设已经对pandas有基础性的了解,核心是Series和DataFrame概念(numpy库可不了解)

一、数据读取和写入

第一步,先从存量数据源,将数据读取过来,然后再将分析得出的数据写入并永久保存,这是数据分析的开始和结束,在此一并说明,主要只讲解常用的读取和写入方式,其他的可以自行学习和了解

1.1 CSV和txt文件:

import pandas as pd file_path_read='' file_path_write='' #读入csv或txt文件内数据,以下只罗列了常用的参数 df=pd.read_csv( file_path_read , #指定需读入或写入的文件的路径,可为相对路径,也可为绝对路径 sep= ',' , #指定分隔符 encoding= utf-8 , #指定字符编码格式 usecols=None , #指定需读入的列,列表格式,可为索引[1,2,3]或列明['A','B','C'] names=['A','B','C'] , #可自定义读入数据的列标签 skip_blank_lines=True, #设置是否跳过内容全空的行 nrows=1000, #指定读入的行数 skiprows=[2,5],#指定需跳过的行数 dtype={0:str,'B':'float64'}) #指定列数据读入的格式,可分别对每一列指定读入的数据格式 #将分析好的数据写入csv或txt文件 df.to_csv( file_path_write ) 

1.2 Excel文件:

import pandas as pd file_path_read='' file_path_write='' #从数据源读取数据,并同时指定读入数据的格式,也可不指定,读入后就是一个标准的DataFrame #其他常用的参数,与read_csv一致,不再赘述 df=pd.read_excel(file_path_read ,encoding= utf-8 , usecols=None , names=['A','B','C'] , skip_blank_lines=True, nrows=1000, skiprows=[2,5],dtype={0:str,2:'float64'}) #将分析好的数据写入Excel,并同时指定写入数据的格式,也可不指定 df.to_excel(file_path_write , dtype=str) 

1.3 MYSQL数据库:

import pandas as pd from sqlalchemy import create_engine #1、连接数据库 #其中username为账户名,比如root,password为密码,ip为数据库的ip,如果是本地的一般是localhost,port为端口,database为数据库名 engine = create_engine('mysql+pymysql://username:password@ip:port/database') #2、定义查询sql语句 sql = '''select * from tablename where colname in (,) ''' #3、读取数据,使用以上数据库引擎和sql语句查询数据,直接读入,为DataFrame格式 #coerce_float,很有用,为true时会将字符串格式的数据直接读取为float数字格式,columns,列表格式,指定读入的行,一般没用,因为基本会在sql语句中指定 #sql也可以直接为表名,即读入整张表,但一般使用sql语句 df=pd.read_sql(sql, engine, coerce_float=True, columns=None) #4、写入数据,将分析好的数据落库 #tablename为需要写入的表名,if_exists,默认为false,即表存在则不写入,也可设置为'append',即将数据追加到该表内,dtype可指定各个列的数据格式,一般无需指定 df.to_sql('tablename', engine , if_exists='append' ,dtype={}) 

二、数据清洗

2.1 清除不需要的行数据

一般数据源都是csv、txt 或者excel,此时可能源数据内就包含大量异常或不想要的行数据,如果不进行清除,则会严重影响后续数据分析的准确性

当然,如果数据源是mysql等数据库,则可在读取数据的时候,即通过slq命令,将异常或不想要的数据给过滤掉。

2.1.1 清除满足指定条件的行数据

#清除满足指定条件的行数据的表达式 df = df.drop(df[].index) #比如希望清除x列小于0.01或大于10的指定行数据,返回一个清除后的DataFrame #其中的布尔表达式可以有多个,可以用与(&)或(|)非(~)进行连接 df_clear = df.drop(df[(df['x']<0.01) | (df['x']>10)].index) #删除x小于0.01或大于10的行 #或者,比如希望清除A列值为空,或者B列中值小于0的行,然后返回清除后的新的DataFrame df_clear = df.drop(df[(df['A']==‘') | (df['B']<0)].index) 

2.1.2 清除指定的行数据

如果数据源是mysql等数据库,可直接在sql语句中添加筛选条件,不过在分析过程中,可能也需要清除指定的行数据。

#清除指定的行 #drop(list),函数接受一个列表,列表内是指定需删除的行索引 df.drop([index]) #即删除指定行 df.drop([0,1,2,3,4]) #清除前5行 df.drop(range(20)) #清除前20行, 

2.2 清除不需要的列

如果数据源是mysql等数据库,则其实可以在sql语句中,只拉取自己需要的列,如果是从csv或Excel读取,也可在读取数据时,就指定对应需要的列

不过在实际数据分析时,可能在分析过程中产生了新的DataFrame,此时可能需要清除不需要的列。

#执行删除操作时,原df不会变化,一般是返回一个新的DataFra df.drop(['列索引或标签',axis=1]) #删除索引为2,即第三列 df.drop([2],axis=1) #删除索引为0,1,2即第一、第二、第三列 df.drop([0,1,2],axis=1) #删除列标签为A的列 df.drop(['A'],axis=1) #删除列标签为A、B、C的多列 df.drop(['A','B','C'],axis=1) 

2.3 调整列的展示顺序或列标签名

这个步骤一般是为了方便自己观察数据,或者在数据分析接近尾声时,为增强数据可读性,对列的顺序进行调整

#语句如下,使用reindex函数 new_col_list=['B','C','A'] #假设希望将列的展示顺序由A、B、C,调整为B、C、A df.reindex(columns = new_col_list) #调整存量DataFrame的列标签名称,一般用于将默认的列标签修改的更加直观易懂 new_col_name=['age','name',gender'] df.columns=new_col_name 

2.4 对行数据进行排序

此处也是为了在进行数据分析时观察数据,或者增强输出的数据的可读性

2.4.1 sort_values()

即按照实际的数据值进行排序

#df.sort_values()函数 #既可以根据列数据,也可根据行数据排序,最为常用 #axis,默认为0,即纵向排序,可指定按照哪列的值进行排序,最终会改变数据纵向的顺序 #axis,为1时,即横向排序,可指定按照哪行(根据行索引)进行排序,最终会改变数据的横向顺序 #inplace, #ascending,可为数组格式,即指定按照多行或列,不同行或列的升序降序规则 #na_position,指定缺省值排在最前还是最后,一般是last,即最后 df.sort_values(by=, axis=0, ascending=True, inplace=False, kind='quicksort', na_position='last') #假设数据如下: b a c 2 1 4 1 0 2 3 3 3 2 1 2 1 3 2 8 #先按照b降序,再按照a升序排序 df.sort_values(by=['b','a'],axis=0,ascending=[False,True]) #先按照3行升序排序,再按照0行降序排序 df.sort_values(by=[3,0],axis=1,ascending=[True,False]) 

2.4.2 sort_index()

#df.sort_index()函数 #默认根据行标签对所有行排序,或根据列标签对所有列排序,或根据指定某列或某几列对行排序。 #axis,默认为0,即按行标签进行排序,最终会改变数据在纵向的顺序 #axis,为1时,即按列标签排序,最终会改变数据在横向的顺序 #na_position,指定缺省值排在最前还是最后,一般是last,即最后 df.sort_index(axis=0, ascending=True , na_position='last') #假设数据如下: b a c 2 1 4 1 0 2 3 3 3 2 1 2 1 3 2 8 #按照行标签升序排序,最后会变成0、1、2、3 df.sort_index(axis=0,ascending=True) #按照列标签升序排序,最后会变成a、b、c df.sort_index(axis=1,ascending=True) 

2.5 空值的处理

一般导入的数据,会存在空值的情况,为了避免此类数值影响后续的数据分析,一般需要进行相应的处理

#1、对空值直接清除 df.dropna( axis=0, # 0: 对行进行操作; 1: 对列进行操作 默认为0 how='any' # 'any': 只要存在 NaN 就 drop 掉; 'all': 必须全部是 NaN 才 drop 默认为'any' ) #2、对空值填补 df.fillna(value=0) #用0填补所有的空值 df.fillna({'B': 3,'C': 4}) #使用常量填补对应列的空值,比如针对B列,用3填补空值,针对C列,用4填补空值 #3、用前项填充或者后项填充 df.fillna(method = 'ffill') #用前一个观测值填充 df.fillna(method = 'bfill') #用后一个观测值填充 #4、用均值或中位数填充各自的列 df.fillna(df.median()) df.fillna(df.mean()) #注:使用fillna,dropna时,需要添加参数 inplace = True,如df.fillna(df.median(),inplace = True),以确认修改,否则实际的数据并不会有改动。 

2.6 数据去重处理

一般源数据可能会在某列存在重复数据的问题,为方便后续处理等,可能需要进行去重

#删除重复行时,需要用到drop_duplicates函数 df.drop_duplicates( ['A','B'], #指定按照某列,判断数据重复,参数非必填,可以单列、多列 keep='first' #指定如果发现重复,保留哪行数据,枚举有first(保留第一行)、last(保留最后一行),False(删除所有重复行) ) df.drop_duplicates() #删除完全重复的行数据 

2.7 对指定列数据进行初步加工

#1、map()函数 #可对一列数据,统一给一列(Series)中的每一个元素应用指定函数 def myfunc(x): if x>40: return '中年人' elif x<30: return '青年人' else: return '尴尬的年纪' df['age'].map(myfunc) #2、apply()函数 #也可对一列数据,统一应用指定函数,但功能更强大,可传入除列元素的其他参数 #其他参数可以关键词的方式传入,也可以直接传入其他值 def myfunc(x,*args,**args_dict): if x<10000: return x+args_dict['high'] else: return x+args_dict['low'] df1['salary']=df1['salary'].apply(myfunc,low=100,high=300)#对工资列,低于1万的加一个值,高于1万的,加另外一个值 

2.8 对DataFrame内所有数据进行初步加工处理

此种方法不太常用,或者可以作为填充默认值的方式,比如将NAN的值填充为0

#以下会对DataFrame每个元素应用一次指定的函数,并将返回值作为新的值 #一般会产生一个新的df #以下函数将空值全部填充为0 df_new=df.apply(lambda x: 0 if str(x)=='' else x) 

2.9 设置数据格式

一般在后续数据处理时,或者在数据处理基本宣告尾声时,为增强数据可读性或者分析的方便,需要对数据设置格式

#以下主要演示对某df内某列数据进行常见的数字格式设置 #四舍五入 df['salary'].round([decimals=2]) #将工资列,数字进行四舍五入并保留小数点后2位 #将小数设置为百分数,以下设置为精确到小数点后2位,返回一个设置好格式的series df['percent'].map( lambda x: format(x,'.2%') ) #设置千分位分隔符,返回一个设置好格式的series df['percent'].map( lambda x: format(x,',') ) #更多设置格式的方式,可自行了解 

三、数据切片和筛选查询

一般需要对清洗后的数据,按照具体数据分析的需求,提取部分数据并进行进一步的分析,这个时候就需要对数据进行进一步切片或查询筛选,找出自己想要的具体数据集

3.1 行切片

提取指定的行,一般是由行索引组成的列表,即提取指定的某行或某几行

#1、直接使用索引 df[index:index+1] #注意,一定要用切片的形式,如果希望直接使用index,则可用iloc[index] #2、使用行标签,行标签为再创建DataFrame或Series时自定义的行标签 df['row_tag'] #提起的方法,可以直接使用标准的列表访问方式[],也可使用loc()和iloc(函数) #[]方式,可使用标签或索引,如果传入的是 #loc()函数,一般用于使用行或列标签进行访问 #iloc()函数,一般使用行或列index索引进行访问 df[2:5] #提取第3到5行 df['2020-10-20'] #提取行标签为2020-10-20的行数据 df.loc['2020-10-20':'2020-10-31',:] #提取指定3到5行,全列,后面的 : 也可不写 df.loc[2:4,:] #提取指定3到5行,全列,后面的 : 也可不写 

3.2 列切片

提取指定的一列或多列,一般使用列标签或列索引进行提取

df['colname'] #直接提取指定单列标签的列数据 df[['A','D','E']] #指定直接提取指定多列数据,这种方法只能使用列标签进行提取 df.loc[:,'A':'C'] #使用loc方法提取A列到C列 df.iloc[:,0:2] #使用iloc方法提取第1到3列 

提示: 本文由整理自网络,如有侵权请联系本站删除!
本站声明:
1、本站所有资源均来源于互联网,不保证100%完整、不提供任何技术支持;
2、本站所发布的文章以及附件仅限用于学习和研究目的;不得将用于商业或者非法用途;否则由此产生的法律后果,本站概不负责!

-六神源码网