cycdfixle 2021-02-19 11:53 采纳率: 100%

# 时间序列数据，python预处理

• 写回答

#### 5条回答默认 最新

• ProfSnail 2021-02-19 11:57
关注

代码编辑完成，基本实现三个需求。

``````# coding='utf-8'

import os
import datetime
import shutil
import openpyxl

pathOri = r'C:\Coding\Python\CSDN\dateSequence'

xlsxName = 'input.xlsx'
outputName = 'output.xlsx'

def getDate(value):
# 因为excel里面保存的可能是日期格式，也可能是字符串形式。
if(str(value.__class__) == "<class 'datetime.datetime'>"):
# datetime.datetime格式
return value
else:
# 字符串格式。
value_list = value.split('/')
year = int(value_list[0])
month = int(value_list[1])
day = int(value_list[2])
rowDay = datetime.date(year, month, day)
return rowDay

def dealEachSheet(inputSheet, outputSheet):
inputRows = inputSheet.max_row
inputCols = inputSheet.max_column
# 将表头原样复制到新文件中
for i in range(1, 3):
for j in range(1, inputCols+1):
outputSheet.cell(row=i, column=j).value = inputSheet.cell(i, j).value

outputSheet.cell(row=1, column=3).value = "周"
outputSheet.cell(row=1, column=4).value = "星期"

# 假设日期是第二列
dateColumn = 1
valueColumn = dateColumn + 1
weekIndexColumn = dateColumn + 2
weekdayColumn = dateColumn + 3

valueDict = {}

# 记下来上一条记录是几月几号
lastDate = None
for i in range(3, inputRows+1):
eachDate = getDate(inputSheet.cell(i, dateColumn).value)
if(eachDate.weekday() != 4):
# 因为是从上到下遍历，所以如果不是周五，则优先填充上一周。
if eachDate.weekday() < 4:
eachDate = eachDate + datetime.timedelta(days=-3-eachDate.weekday())
else:
eachDate = eachDate + datetime.timedelta(days=4-eachDate.weekday())
# 填充上一周
if(eachDate != lastDate):
pass
# 填充到这一周
else:
eachDate = eachDate + datetime.timedelta(days=7)
inputSheet.cell(i, dateColumn).value = eachDate
valueDict[eachDate] = inputSheet.cell(i, valueColumn).value

startDate = getDate(inputSheet.cell(3, 1).value)
endDate = getDate(inputSheet.cell(inputRows, 1).value)

week53Dates = []

eachDate = startDate
lastDate = eachDate
while eachDate != endDate:
# 遍历所有的周五，进行数据插值
eachDate = eachDate + datetime.timedelta(days=7)
if eachDate not in valueDict.keys():
# 如果这一周是个缺失数值，则找到字典中有数值的上一个和下一个，并取这两个数值的平均数
# 如果有多个缺失值，比如说是1 缺失 缺失 缺失 10
# 则首先补充第一个，补充为  1 5.5 缺失 缺失 10
# 接下来补充第二个，补充为  1 5.5 7.75 缺失 10
# 接下来补充第三个，补充为  1 5.5 7.75 8.875 10
# 采用的是二分插值方法。
# 因为每次填充之后，上一个日期总是在列表中的，所以只需要找到下一个进行插分即可。
nextDate = eachDate + datetime.timedelta(days=7)
while nextDate not in valueDict.keys():
nextDate = nextDate + datetime.timedelta(days=7)
valueDict[eachDate] = (valueDict[lastDate] + valueDict[nextDate]) / 2;
lastDate = eachDate
# 在这次遍历中，同时记录一下有53周的日期
if eachDate.isocalendar()[1] == 53:
week53Dates.append(eachDate)

# 如果有53周，则用51周五和第二年第一周的日期中间值进行替代。
for eachWeek53Date in week53Dates:
# 第二年第一周周五
week1date = eachWeek53Date + datetime.timedelta(days=7)
# 第一年第51周周五
week51date = eachWeek53Date + datetime.timedelta(days=-14)
# 第一年第52周周五
week52date = eachWeek53Date + datetime.timedelta(days=-7)
diff = (week1date - week51date) / 2

# 计算51周周五和第二年第一周周五的中间那一天
midDate = week51date + datetime.timedelta(days=diff.days)
# 计算中间那一天的数值
midValue = (valueDict[week51date] + valueDict[week1date]) / 2
# 删除第52周和53周
valueDict.pop(eachWeek53Date)
valueDict.pop(week52date)
valueDict[midDate] = midValue

keys = sorted(valueDict)

id = 3
weekDict = {0:'星期一',1:'星期二',2:'星期三',3:'星期四',4:'星期五',5:'星期六',6:'星期日'}
for key in keys:
outputSheet.cell(id, dateColumn).value = key.strftime('%Y/%m/%d')
outputSheet.cell(id, valueColumn).value = valueDict[key]
outputSheet.cell(id, weekIndexColumn).value = key.isocalendar()[1]
outputSheet.cell(id, weekdayColumn).value = weekDict[key.weekday()]
id += 1

def main():
# 读取文件
# 因为原始数据中有许多地方是用公式进行计算得到的，需要指定data_only=True使得读入的时候就是完整的数值。
# 比如A286=A285+7等
inputSheet = inputWorkbook[inputWorkbook.sheetnames[0]]

# 输出文件
outputWorkbook = openpyxl.Workbook()
outputSheet = outputWorkbook.active
outputSheet.title = inputWorkbook.sheetnames[0]

# 处理文件
dealEachSheet(inputSheet, outputSheet)
for i in range(1, len(inputWorkbook.sheetnames)):
sheetName = inputWorkbook.sheetnames[i]
inputSheet = inputWorkbook[sheetName]
outputSheet = outputWorkbook.create_sheet(sheetName)
dealEachSheet(inputSheet, outputSheet)

outputWorkbook.save(os.path.join(pathOri, outputName))

if __name__ == '__main__':
main()``````
本回答被题主选为最佳回答 , 对您是否有帮助呢?
评论

#### 悬赏问题

• ¥200 csgo2的viewmatrix值是否还有别的获取方式
• ¥15 Stable Diffusion，用Ebsynth utility在视频选帧图重绘，第一步报错，蒙版和帧图没法生成，怎么处理啊
• ¥15 请把下列每一行代码完整地读懂并注释出来
• ¥15 pycharm运行main文件，显示没有conda环境
• ¥15 易优eyoucms关于二级栏目调用的问题
• ¥15 寻找公式识别开发，自动识别整页文档、图像公式的软件
• ¥15 为什么eclipse不能再下载了？
• ¥15 编辑cmake lists 明明写了project项目名，但是还是报错怎么回事
• ¥15 关于#计算机视觉#的问题：求一份高质量桥梁多病害数据集
• ¥15 特定网页无法访问，已排除网页问题