天天看點

# yyds幹貨盤點 #手把手教你使用Pandas從Excel檔案中提取滿足條件的資料并生成新的檔案(附源碼)

大家好,我是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置空,如此反複,這樣就可以每次取到每天唯一的某一個小時的一個時間。

三、總結