大家好,我是Python進階者。
一、前言
前幾天在Python星耀交流群有個叫【蔣衛濤】的粉絲問了一個Python自動化辦公的題目,這裡拿出來給大家分享。
下面是他的原始資料。
二、實作過程
這裡【月神】、【瑜亮老師】分别給出了5種可行的方法,分享給大家。
方法一:分别取日期與小時,按照日期和小時删除重複項
import pandas as pd
excel_filename = '資料.xlsx'
df = pd.read_excel(excel_filename)
# print(df)
# 方法一:分别取日期與小時,按照日期和小時删除重複項
df['day'] = df['SampleTime'].dt.day # 提取日期列
df['hour'] = df['SampleTime'].dt.hour # 提取小時列
df = df.drop_duplicates(subset=['day', 'hour']) # 删除重複項
# 把篩選結果儲存為excel檔案
df.to_excel('資料篩選結果2.xlsx')
方法二:把日期中的分秒替換為0
import pandas as pd
excel_filename = '資料.xlsx'
df = pd.read_excel(excel_filename)
# 方法二:把日期中的分秒替換為0
SampleTime_new = df['SampleTime'].map(lambda x: x.replace(minute=0, second=0))
data = df[SampleTime_new.duplicated() == False]
print(df)
# 把篩選結果儲存為excel檔案
df.to_excel('資料篩選結果2.xlsx')
方法三:對日期時間按照小時進行分辨
import pandas as pd
excel_filename = '資料.xlsx'
df = pd.read_excel(excel_filename)
# 方法三:對日期時間按照小時進行分辨
SampleTime_new = df['SampleTime'].dt.floor(freq='H')
df = df[SampleTime_new.duplicated() == False]
print(df)
# 把篩選結果儲存為excel檔案
df.to_excel('資料篩選結果2.xlsx')
方法四:對日期時間按照小時進行分辨
import pandas as pd
excel_filename = '資料.xlsx'
df = pd.read_excel(excel_filename)
# 方法四:對日期時間按照小時進行分辨
SampleTime_new = df['SampleTime'].dt.to_period(freq='H')
df = df[SampleTime_new.duplicated() == False]
print(df)
# 把篩選結果儲存為excel檔案
df.to_excel('資料篩選結果2.xlsx')
方法五:對日期時間進行重新格式,并按照新的日期時間删除
import pandas as pd
excel_filename = '資料.xlsx'
df = pd.read_excel(excel_filename)
# 方法五:對日期時間進行重新格式,并按照新的日期時間删除重複項(會引入新列)
df['new'] = df['SampleTime'].dt.strftime('%Y-%m-%d %H')
df = df.drop_duplicates(subset=['new'])
print(df)
# 把篩選結果儲存為excel檔案
df.to_excel('資料篩選結果2.xlsx')
小總結
前面這5個方法有相似的地方,比如方法1和方法5都是把日期隻取到小時,方法3和方法4都是按照小時進行分辨,而方法1,2和5其實本質上都是把分鐘和秒變成0,比如方法5中這樣寫的話,就和方法2是一樣的
df['new'] = df['SampleTime'].dt.strftime('%Y-%m-%d %H:00:00')
方法2和3是【月神】提供的方法,方法1,4,5是【瑜亮老師】提供的方法。
【月神】使用了
floor
向下取整,也就是抹去零頭。本來【瑜亮老師】還想用
ceil
向上取整試試,結果發現不對,整點的會因為向上取整而導緻資料缺失,比如
8:15
,向上取整就是
9
點,如果同一天中剛好
9:00
也有一條資料,那麼這個
9
點的資料就會作為重複的資料而删除。本來應該是
8
點
9
點各取1條資料的,結果變成了隻取
8
點這1條。包括round,也會因為四舍五入(這裡就不糾結了)導緻資訊缺失更多。
方法六:使用openpyxl處理
這裡我本來還想用
openpyxl
進行實作,但是卻卡殼了,隻能提取出24條資料出來,先放這裡做個記錄吧,哪天突然間靈光了,再補充好了。
from openpyxl import load_workbook, Workbook
from datetime import datetime
# 打開資料工作簿
workbook = load_workbook('資料.xlsx')
# 打開工作表
sheet = workbook.active
time_column = sheet['C']
row_lst = []
date_lst = []
hour_lst = []
for cell in time_column:
if cell.value != "SampleTime" and cell.value != None:
# print(cell.value.date())
if cell.value.date() not in date_lst:
date_lst.append(cell.value.date())
# row_lst.append(cell.row)
print(date_lst)
# if all(cell.value != "SampleTime", cell.value != None, cell.value.date() == date, cell.value.hour not in hour_lst):
for date in date_lst:
# print(date)
for cell in time_column:
# if all((cell.value != "SampleTime", cell.value != None, cell.value.date() == date, cell.value.hour not in hour_lst)):
# row_lst.append(cell.row)
if cell.value != "SampleTime" and cell.value != None:
if cell.value.date() == date:
if cell.value.hour not in hour_lst:
hour_lst.append(cell.value.hour)
row_lst.append(cell.row)
hour_lst = []
print(hour_lst)
# 将滿足要求的資料寫入到新表
new_workbook = Workbook()
new_sheet = new_workbook.active
# 建立和原資料 一樣的表頭(第一行)
header = sheet[1]
header_lst = []
for cell in header:
header_lst.append(cell.value)
new_sheet.append(header_lst)
# 從舊表中根據行号提取符合條件的行,并周遊單元格擷取值,以清單形式寫入新表
for row in row_lst:
data_lst = []
for cell in sheet[row]:
data_lst.append(cell.value)
new_sheet.append(data_lst)
# 最後切記儲存
new_workbook.save('新表.xlsx')
print("滿足條件的新表儲存完成!")
這個方法就是周遊
date
,然後周遊一次之後,将hour置空,如此反複,這樣就可以每次取到每天唯一的某一個小時的一個時間。