excel数据清洗-pandas python

这里是针对广东统计年鉴excel数据清洗的一个小总结

反正要复制的代码

  1. 循环读取文件夹,用pandas读取excel
for root, dirs, files in os.walk(path):
    for f in files:
        df = pd.read_excel(os.path.join(root, f),header=None)
        #########神仙操作#########
        df.to_excel(f.lower()+"_output", sheet_name='Sheet1', index=False, header=False)#f.lower是为了排除有的后缀名是.XLS的
        df.to_excel('c_'+f.replace("xlsx", "xls").lower(), sheet_name='Sheet1', index=False, header=False)#这个是简单粗暴直接把xlsx改成了xls
  1. 把空串设为np.nan(非常重要!!)
df.replace(to_replace=r'^\s*$',value=np.nan,regex=True,inplace=True)

dataframe常用代码

df.iloc[row,col] #读取某个单元格
df.shape[0] #行数
df.shape[1] #列数
df.shape() #返回行和列
df = df.dropna(how='all') #删除空行(how=全为空)
df = df.dropna(axis=1,how='all') #删除空列
df = df.head(i) #只保留前i行df

查找与替换代码

  1. 注意事项:
    进行这类操作前要先判断一下 df.iloc[] is None 或 pd.isnull(df.iloc[]) 或pd.isna(df.iloc[])
    还要注意str(df.iloc[]) ,不然会报错哦
  2. python自带的一些函数
#if df.iloc[i,j] is not None: 
#	df.iloc[i,j]=str(df.iloc[i,j])
	df.iloc[i, j].replace("new", "old")  
	fstr="aa"
	df.iloc[i, j].find(fstr) #返回找到的字符串所在位置,即0~len-1,没找到返回-1,好像还有rfind()?
  1. 正则表达式相关
    菜鸟的正则表达式在线测试工具:https://c.runoob.com/front-end/854
    这里用的比较多的是match()和search()两个函数,其他见另一篇~
    https://blog.csdn.net/qq_43103270/article/details/114382838
import re
rule=re.compile(r'[\u4e00-\u9fa5]{1,}')#包含中文字符
#找有或没有
if rule.match(str(df.iloc[i, j])) is not None: print("有")
#只保留中文
df.iloc[i, j]=rule.search(str(df.iloc[i, j])).group() 

一些特例

  1. 针对pandas似乎把年份也处理为浮点数的情况:
#处理年份变为浮点数的情况
for i in range(0, min(10,df.shape[0])):#这里是感觉前10行够了,以防万一要加一个min!
    for j in range(0, df.shape[1]):
        if df.iloc[i,j] in range(1800,2020,1):
        	df.iloc[i,j]=str(int(df.iloc[i,j]))
  1. 针对一些逻辑删除,即行或者列里面只有0和0.0和""和nan的
#删掉某列为0和''的列
count=0
for j in range(0,df.shape[1]):
    for i in range(0,df.shape[0]):
        if df.iloc[i,j]=='0' or df.iloc[i,j]=="" or df.iloc[i,j]=="0.0"or pd.isna(df.iloc[i,j]):
            count=count+1
    if count==df.shape[0]:
        for i in range(0,df.shape[0]):
            if df.iloc[i,j]=='0' or df.iloc[i,j]=="0.0":
                df.iloc[i,j]=np.nan
    count=0
#删掉某行为0和''的行
count=0
count2=0
for i in range(0,df.shape[0]):
    for j in range(1,df.shape[1]):
        if df.iloc[i,j]=='0'or df.iloc[i,j]=="0.0" or df.iloc[i,j]==""or pd.isna(df.iloc[i,j]):
            count=count+1
            if df.iloc[i,j]==""or pd.isna(df.iloc[i,j]):
                count2=1   
    if count==df.shape[1]-1 and count2==1:
        for j in range(0,df.shape[1]):
            if df.iloc[i,j]=='0' or df.iloc[i,j]=="0.0":
                df.iloc[i,j]=np.nan
    count=0
    count2=0
#根据情况在后面dropna()
  1. 针对合并单元格的重复标题(这里的标题在第一行和第二行),要求只保留第一个
#处理重复标题
if df.iloc[0,1] is not np.nan:                
    for j in range(1,df.shape[1]):
        df.iloc[0,j]=np.nan
if df.iloc[1,0] is not np.nan and str(df.iloc[1,0])==str(df.iloc[0,0]):
    for j in range(0,df.shape[1]):
         df.iloc[1,j]=np.nan

其他

  1. 用了dropna() head()等函数记得赋值,不然等于白用
  2. 处理标题行如果不用find_first_data()函数的话记得要加个min(x,df.shape[0]),小心超出索引
  3. 用字符串或赋值等相关代码的时候记得数据类型得是字符串
  4. 删除行、列要用索引,如果没有的话就老实直接nan然后dropna吧,如果以后有更好的办法再补充
  5. 代码写得可真烂呀 以后加油整成函数吧 加油加油
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值