Excel中有个非常好用且常用的功能就是自动填充,想必常用excel的小伙伴都了解,那么python能否实现这个功能呢?答案是肯定的,pandas模块可以很好的完成这项工作,而且更加灵活。一起来看下如何用代码实现吧。
首先,我们需要一个测试文件,路径位于本人的电脑桌面,名为“填充.xlsx”,如下截图,长的就像箭头左边那样;现在我要把它做一个自动填充,填充结果成箭头右边那样。
我们的要求是:
- “编号”,使用数字填充
- “状态”,使用“yes”,“no”交替填充
- “日期1”,以天的维度依次递增
- “日期2”,以月份的维度依次递增
- “日期3”,以年的维度依次递增
该如何实现呢?我们先理一下解决思路,这个问题我们大概要分两步走:
第一步:读取数据
第二步:分别填充编号,状态,日期1,2,3
我们分别看下代码实现:
读取数据
上一篇文章已经介绍了pandas读取文件的方法,就是使用read_excel()了,我们用jupyter notebook看下于运行结果:
读取的数据并不是向我们想象中的区域,我们的源数据并不是顶格写的,这种情况pandas会把空行和空列自动读取,我们想要只保留数据区域,read_excel()中的“skiprows”参数用于跳过空行,“usecols”参数用来指定选取列区域,这样就可以跳过空行和列,选取我们想要的数据区域啦!附上代码:
import pandas as pd
df=pd.read_excel(r'C:\Users\XZC43\Desktop\填充.xlsx',skiprows=4,usecols="C:H",index_col=None)
print(df)
运行结果如下:
成功读取到我们想要的数据区域,记得用index_col参数把第一行作为column索引。
填充字段
- 填充“编号”字段
构造for循环遍历添加数值:
for i in df.index:
df['编号'].at[i]=i+1
print(df)
运行结果如下:
成功填充编号字段,但是细心的小伙伴发现了,填充值的类型是float类型的,我们想要的是int类型的,read_excel()中的dtype字段可以设置字段类型,如果直接设置编号字段为int类型,会报错,因为在填充语句运行时,编号字段是存在空值的,空值是无法转换成int整型的,所以,我们要设置dtype参数为str类型。剩下需要填充的字段同理,需要修改读取文件的代码如下:
df=pd.read_excel(r'C:\Users\XZC43\Desktop\填充.xlsx',skiprows=4,usecols="C:H",index_col=None,dtype={'编号':str,'状态':str,'日期1':str,'日期2':str,'日期3':str,})
- 填充“状态”字段
在上述for循环的基础上,利用if判断语句实现:
for i in df.index:
df['状态'].at[i]='yes' if i%2==0 else 'no'
print(df)
运行结果如下:
成功填充状态字段。
- 填充“日期1”字段
需要导入datetime模块,设置一个开始日期,利用for循环遍历添加日期:
from datetime import date,timedelta
start=date(2019,4,1) #设置起始日期为“2019-04-01”
for i in df.index:
df['日期1'].at[i]=start+timedelta(days=i)
print(df)
运行结果如下:
成功填充日期1字段。
- 填充“日期2”字段
可惜的是,timedelta函数只有day参数,没有month或year参数,所以我们需要单独计算年和月,其中年份的计算比较方便,所以先讲“日期3”字段的填充,直接for循环遍历,使用date()函数定义新的年,月,日即可:
for i in df.index:
df['日期3'].at[i]=date(start.year+1,start.month,start.day)
print(df)
运行结果如下:
成功填充“日期3字段”。
- 填充“日期2“字段
该字段之所以最后说,因为月份的填充以上两种方法都不可用,月份只有12个月,牵扯到超过12个月需要递进一年的逻辑,单纯的加数字是无法做到的,这里需要构造一个添加月份的函数,我直接贴上代码,大家可以理解下它的逻辑:
def addmonth(d,md):
'''d(日期),md(月份差),yd(年份差),m(月份)'''
yd=md//12
m=d.month + md%12
if m!=12:
yd += m//12
m=m%12
return date(d.year+yd, m, d.day)
for i in df.index:
df['日期2'].at[i]=addmonth(start,i)
print(df)
运行结果如下:
成功填充日期2字段。
好啦!五个字段均按照我们的要求成功填充,最后我们保存下文件,还是放在桌面,名为“填充结果.xlsx”即可。最后整理一下代码如下:
import pandas as pd
from datetime import date,timedelta
def addmonth(d,md):
'''d(日期),md(月份差),yd(年份差),m(月份)'''
yd=md//12
m=d.month+md%12
if m!=12:
yd += m//12
m=m%12
return date(d.year+yd,m,d.day)
df=pd.read_excel(r'C:\Users\XZC43\Desktop\填充.xlsx',skiprows=4,usecols="C:H",index_col=None,dtype={'编号':str,'状态':str,'日期1':str,'日期2':str,'日期3':str})
start=date(2019,4,1)
for i in df.index:
df['编号'].at[i]=i+1
df['状态'].at[i]='yes'if i%2==0 else 'no'
df['日期1'].at[i]=start+timedelta(days=i)
df['日期3'].at[i]=date(start.year+i,start.month,start.day)
df['日期2'].at[i]=addmonth(start,i)
df.set_index('编号')
df.to_excel(r'C:\Users\XZC43\Desktop\填充结果.xlsx')
print('完成!')
结束。