1. 程式人生 > 其它 >Day12-Python綜合練習2(DataWhale)

Day12-Python綜合練習2(DataWhale)

技術標籤:Pythonpython資料分析

一、顯示卡日誌

下面給出了3090顯示卡的效能測評日誌結果,每一條日誌有如下結構:

Benchmarking #2# #4# precision type #1#

#1# model average #2# time : #3# ms

其中#1#代表的是模型名稱,#2#的值為train(ing)或inference,表示訓練狀態或推斷狀態,#3#表示耗時,#4#表示精度,其中包含了float, half, double三種類型

Benchmarking 2(Inference) 4(float) precision type 1(resnet50)
1(resnet50) model average 2(inference) time : 3(13.426570892333984) ms

問題:整理為如下樣式

請把日誌結果進行整理,變換成如下狀態model_i用相應模型名稱填充,按照字母順序排序,數值保留三位小數:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-UX850xtL-1610545546369)(attachment:image.png)]

思路

1.觀察給定的資料,首先需要做的是將資料匯入進來

2.將1,2,3,4的資料提取出來

3.將2和4組合為列,1為行,3作為值

import pandas as pd 
import numpy as np
import re

【START】

1. 讀取資料

使用re模組讀取兩個值之間的資料,此處可以直接將開始和結尾的多餘資料直接刪除,然後讀取txt檔案,但是考慮到日常的使用,選擇使用這種方式

file = open('benchmark.txt')
keyStart = 'memory_available: 129118310400'
keyEnd = 'benchmark end :  2020/12/24 12:56:47'
buff = file.read()
pat = re.compile(keyStart+'(.*?)'+keyEnd, re.S)
result = pat.findall(buff) #得到我們實際想要的資料
file.close()

2.調整資料格式

上面獲取的資料讀取出來是一個列表,存成了一列,觀察資料發現可以通過/n拆分,但是拆分出來的列表的並沒有按照一條完整的日誌資料來儲存,接著將列表資料拆分為奇數列和偶數列,得到我們想要的一條完整的日誌記錄存在在一行

A = result
#將資料依據\n拆分
A = A[0].split('\n')
#去除多餘資料
A = A[1:len(A)-1]
# 獲取奇數列和偶數列
J = [i for i in A if A.index(i)%2 == 0]
Q = [i for i in A if A.index(i)%2 == 1]
#將奇數列和偶數列拼成DataFrame
df = pd.DataFrame({'A':J,
                  'B': Q})
df.head(2)
AB
0Benchmarking Training float precision type mna...mnasnet0_5 model average train time : 28.527...
1Benchmarking Training float precision type mna...mnasnet0_75 model average train time : 34.10...

3.提取值

A列:提取2,4 ;B列提取1,3

#通過正則提取到2和4
s1 = df['A']
p = 'Benchmarking( \w+)( \w+)'
ext1 = s1.str.extract(p)
s2 = df['B']
#提取到1,2,3。注意獲取浮點型資料的方法
p2 = '(\w+)  model average (\w+) time :  (\d+.\d+)'
ext2 = s2.str.extract(p2)
#拼接1,2,3,4
data = pd.DataFrame({'name': ext2[0],
                    'type': ext1[0]+'_'+ext1[1],
                    'time': round(ext2[2].astype('float'),3)})#擷取為小數點後三位,注意需要轉換為float型
data.head(3)
nametypetime
0mnasnet0_5Training_ float28.528
1mnasnet0_75Training_ float34.105
2mnasnet1_0Training_ float34.314

4. 長表變寬表

data = data.pivot(index='name',columns='type',values='time')
data = data.reset_index()
data.head()
typenameInference_ doubleInference_ floatInference_ halfTraining_ doubleTraining_ floatTraining_ half
0densenet121144.11115.63719.772417.20793.35788.976
1densenet161511.17731.75027.5551290.287136.624144.319
2densenet169175.80821.59826.371511.404104.840121.556
3densenet201223.96026.16933.394654.365129.334118.940
4mnasnet0_511.8708.0396.92948.23228.52827.198

【END】

總結

這道題的總體思路是比較好找到的,但是遇到了幾個問題:

1.首先就是讀取資料,需要排除我們不要的資料,這裡是在網上查找了一個獲取開始和結束值之間資料的方法

2.資料獲取了之後發現存的是一個長字串,觀察之後選擇將資料拆分,需要注意的是要先轉換為字串之後再拆分,拆分完以後,發現我們需要的資料存成了兩行,這裡又將兩行轉換為兩列

上面兩個問題解決後終於將我們的資料整理成了可以進行各種操作的資料集,之後就是通過正則表示式將我們需要的資料提取,然後再進行長寬表變換,最後就得到了我們的最終資料

二、水壓站點的特徵工程

df1和df2中分別給出了18年和19年各個站點的資料,其中列中的H0至H23分別代表當天0點至23點;df3中記錄了18-19年的每日該地區的天氣情況,請完成如下的任務:

df1 = pd.read_csv('yali18.csv')
df2 = pd.read_csv('yali19.csv')
df3 = pd.read_csv('qx1819.csv')
df1.tail(2)
TimeMeasNameH0H1H2H3H4H5H6H7...H14H15H16H17H18H19H20H21H22H23
109482018-12-31站點90.2872500.3018750.306000.305250.3135000.3015000.2797500.253875...0.2415000.2377500.2336250.2276250.2096250.2265000.219750.2115000.2411250.246375
109492018-12-31站點60.3131250.3303750.333750.334500.3371250.3266250.3108750.277875...0.2613750.2591250.2621250.2527500.2415000.2523750.246750.2396250.2692500.269625

2 rows × 26 columns

df2.head(2)
TimeMeasNameH0H1H2H3H4H5H6H7...H14H15H16H17H18H19H20H21H22H23
02019-01-01站點40.3420000.4293750.42900.440250.4458750.4447500.4177500.387000...0.3198750.326250.3236250.3225000.3090000.3071250.3071250.3071250.3071250.307125
12019-01-01站點70.2151250.2395000.25750.246250.2751250.2646250.2293750.205375...0.1806250.176500.1813750.1551250.1596250.1461250.1446250.1352500.1588750.184750

2 rows × 26 columns

1. 通過df1和df2構造df,把時間設為索引,第一列為站點編號,第二列為對應時刻的壓力大小

思路

使用縱向拼接將df1和df2資料集合並,然後需要將H0-H23轉換為對應的時間點,之後通過寬表變長表將日期和時間匹配

【START】

1. 拼接資料

df = pd.concat([df1,df2],axis=0,join='outer')
df.head(2)
TimeMeasNameH0H1H2H3H4H5H6H7...H14H15H16H17H18H19H20H21H22H23
02018-01-01站點40.4027500.4076250.4181250.4252500.4260.425250.4173750.426375...0.3487500.359250.355500.344250.3521250.356250.347250.3438750.3566250.418875
12018-01-01站點70.2143750.2267500.2323750.2331250.2350.232750.2308750.220000...0.1873750.196750.199750.192250.1862500.183250.177250.1633750.1652500.199375

2 rows × 26 columns

2. 將H0-H23替換為時間值

#1.使用正則將H去除
timet = pd.Series(df.columns[2:])
p = 'H(\d+)'
timet = timet.str.extract(p)[0].to_list()
#2.在前面填充0,否則在後面拼接的時候0:00:00不顯示
timet = [' '+i.zfill(2)+':00:00' for i in timet]
#3.替換原來的列名,這裡將列名補全,可以直接替換
timet1 = ['Date','站點']+timet
df.columns = timet1
df.head(2)
Date站點00:00:0001:00:0002:00:0003:00:0004:00:0005:00:0006:00:0007:00:00...14:00:0015:00:0016:00:0017:00:0018:00:0019:00:0020:00:0021:00:0022:00:0023:00:00
02018-01-01站點40.4027500.4076250.4181250.4252500.4260.425250.4173750.426375...0.3487500.359250.355500.344250.3521250.356250.347250.3438750.3566250.418875
12018-01-01站點70.2143750.2267500.2323750.2331250.2350.232750.2308750.220000...0.1873750.196750.199750.192250.1862500.183250.177250.1633750.1652500.199375

2 rows × 26 columns

3.將寬表變為長表

#轉換為長表,然後將日期和時間拼接為一個欄位
df_melted = df.melt(id_vars=['Date','站點'],
                   value_vars=timet,
                   var_name='Time2',
                   value_name='壓力')
df_melted['Time'] = pd.to_datetime(df_melted['Date']+df_melted['Time2'])
df_new = df_melted[['Time','站點','壓力']]
#將Time作為索引
df_new = df_new.set_index('Time')
df_new.tail(3)
站點壓力
Time
2019-12-31 23:00:00站點20.332000
2019-12-31 23:00:00站點90.201375
2019-12-31 23:00:00站點60.000000

【END】

2. 在上一問構造的df基礎上,構造下面的特徵序列或DataFrame,並把它們逐個拼接到df的右側

2.1 當天最高溫、最低溫和它們的溫差

df3.head(3)
日期天氣氣溫風向
02018-01-01多雲1C~-4C東南風 微風
12018-01-02陰轉多雲8C~0C東北風 3-4級
22018-01-03陰轉小雪1C~-1C東北風 4-5級轉4-5級

【START】

思路

首先我們需要將df3的氣溫拆成最低氣溫和最高氣溫,並存成數值型,計算出溫差使用join拼入df中

#刪除氣溫為空的值
df_t = df3.dropna(how='any',subset=['氣溫'])
s = df_t['氣溫']
#將空格和℃替換為統一值,方便正則取值
s = s.str.replace(' ','')
s = s.str.replace('℃','C')
#正則表示式取出溫度
p = '(\d+)C~(\S\d+|\d+)'
ext = s.str.extract(p)
#由於存在沒有最低溫度的值,這裡選擇不為na的值
ext = ext[ext[0].isna()==False]
#將型別轉換為int型,方便計算差值
ext[0] = ext[0].astype(int)
ext[1] = ext[1].astype(int)
ext[2] = ext[0] - ext[1] 
ext.head(2)
012
01-45
1808

上面一步出現了問題:首先是會有存在空格的現象,採用替代的Day3-Index.ipynb將空格刪除出;另一個會有沒有最低溫度的值,因為只有兩條,這裡選擇將其刪除

#使用索引拼接的方式,上面刪除na值不會影響到索引號
df_t = df_t.join(ext,how='outer')
#對列名重新命名
df_t = df_t.rename(columns = {0:'最高氣溫',1:'最低氣溫',2:'溫差'})
df_t = df_t[['日期','最高氣溫','最低氣溫','溫差']]
df_t['日期'] = pd.to_datetime(df_t['日期'])
df_te = df_new.copy()
#對第1小問生成的df_new進行改造,建立拼接欄位date
df_m = df_te.reset_index(drop=False)
#注意使用merge的時候,兩個日期的型別要一致
df_m['date'] = pd.to_datetime(df_m['Time'].dt.date)
df_l = df_m.merge(df_t, left_on = 'date', right_on='日期', how='left')
df_l.head(2)
Time站點壓力date日期最高氣溫最低氣溫溫差
02018-01-01站點40.4027502018-01-012018-01-011.0-4.05.0
12018-01-01站點70.2143752018-01-012018-01-011.0-4.05.0

【END】

2.2 當天是否有沙暴、是否有霧、是否有雨、是否有雪、是否為晴天

思路

我們想要返回布林型別,因此可以直接使用str.contains,然後再拼接資料

【START】

df_w = df3.copy()
#日期型別轉換
df_w['日期'] = pd.to_datetime(df_w['日期'])
s = df_w['天氣']
s1 = s.str.contains('沙|暴')
#此處注意一定要重新命名,預設名稱為天氣,在join的時候會報錯
s1 = s1.rename('是否沙暴')
s2 = s.str.contains('霧')
s2 = s2.rename('是否有霧')
s3 = s.str.contains('雨')
s3 = s3.rename('是否有雨')
s4 = s.str.contains('雪')
s4 = s4.rename('是否有雪')
s5 = s.str.contains('晴')
s5 = s5.rename('是否晴天')
#將上面的結果拼接到df_w中
df_w = df_w.join(s1,how='left')
df_w = df_w.join(s2,how='left')
df_w = df_w.join(s3,how='left')
df_w = df_w.join(s4,how='left')
df_w = df_w.join(s5,how='left')
df_w.tail(2)
日期天氣氣溫風向是否沙暴是否有霧是否有雨是否有雪是否晴天
7272019-12-30陰轉晴4℃~-6℃東北風轉北風 4-5級轉4-5級FalseFalseFalseFalseTrue
7282019-12-31晴轉多雲0℃~-5℃西風轉南風 <3級FalseFalseFalseFalseTrue
#將df_w資料拼接到df_l
df_l = df_l.merge(df_w, left_on = 'date', right_on='日期', how='left')
df_e = df_l[['Time','站點','壓力','date','天氣','氣溫','風向','最高氣溫','最低氣溫','溫差','是否沙暴','是否有霧','是否有雨','是否有雪','是否晴天']]
df_e.tail(2)
Time站點壓力date天氣氣溫風向最高氣溫最低氣溫溫差是否沙暴是否有霧是否有雨是否有雪是否晴天
5255982019-12-31 23:00:00站點90.2013752019-12-31晴轉多雲0℃~-5℃西風轉南風 <3級0.0-5.05.0FalseFalseFalseFalseTrue
5255992019-12-31 23:00:00站點60.0000002019-12-31晴轉多雲0℃~-5℃西風轉南風 <3級0.0-5.05.0FalseFalseFalseFalseTrue

【END】

2.3 選擇一種合適的方法度量雨量/下雪量的大小(構造兩個序列分別表示二者大小)

思路

雨量使用水壓站點當天的最大壓力來度量,下雪量的大小通過天氣中的雪的型別來區分,設定為分類資料型別

【START】

雨量的分類

#篩選出有雨的資料
df_y = df_e[df_e['是否有雨']==True]
gb = df_y.groupby('date')['壓力'].max()
#依據gb的最大值和最小值來進行分組,分為小、中、大、特大四類
print(gb.min())
print(gb.max())
0.40424999594688416
1.4006251096725464
#對雨量進行分類
s = pd.cut(gb, bins=4, labels=['小','中','大','特大'])

雪量的分類

#篩選出有雪的資料
df_x = df_e[df_e['是否有雪']==True]
pat = '(\w雪)'
typ = df_x['天氣'].str.extract(pat)
typ[0].unique()
#我們發現提取後,雪的分類可以設定為四類,現在需要將四類作為有序分類
array(['小雪', '中雪', '夾雪', '大雪'], dtype=object)
#設定為有序分類
typ = typ[0].astype('category')
typ = typ.cat.reorder_categories(['夾雪','小雪', '中雪', '大雪'],ordered=True)

將雨和雪的分類拼接

#修改為DataFrame,s使用值連線
s = pd.DataFrame(s)
s = s.reset_index()
df_f = df_e.merge(s,on ='date',how='left')
#typ使用索引連線
typ = pd.DataFrame(typ)
df_f = df_f.join(typ,how='outer')
df_f = df_f.rename(columns={'壓力_x':'壓力','壓力_y':'雨量大小',0:'雪量大小'})
df_f[df_f['是否有雨']==True].head(2)
Time站點壓力date天氣氣溫風向最高氣溫最低氣溫溫差是否沙暴是否有霧是否有雨是否有雪是否晴天雨量大小雪量大小
4502018-01-16站點40.3963752018-01-16雨夾雪轉陰4C~-1C東北風轉南風 3-4級轉3-4級4.0-1.05.0FalseFalseTrueTrueFalse夾雪
4512018-01-16站點70.2095002018-01-16雨夾雪轉陰4C~-1C東北風轉南風 3-4級轉3-4級4.0-1.05.0FalseFalseTrueTrueFalse夾雪

【END】

2.4 限制只用4列,對風向進行0-1編碼(只考慮風向,不考慮大小)

思路

首先檢視一下風向的種類,發現有很多類別,這裡選取後兩位作為它的主要風向(這裡我認為並不是最優的)

【START】

#獲取風向的資料,並以後兩位作為主要風向
p ='(轉\w+風|\w+風)'
df_d  = df_f['風向'].str.extract(p)
df_d = pd.DataFrame([str(i)[-2:] for i in df_d[0].to_list()])
#轉換為4列0-1編碼
df_d = pd.get_dummies(df_d[0])
df_d = df_d[['東風','西風','南風','北風']]
#將風向資料拼入df_f,索引連線
df_h = df_f.join(df_d,how='outer')
df_h.tail(2)
Time站點壓力date天氣氣溫風向最高氣溫最低氣溫溫差...是否有霧是否有雨是否有雪是否晴天雨量大小雪量大小東風西風南風北風
5255982019-12-31 23:00:00站點90.2013752019-12-31晴轉多雲0℃~-5℃西風轉南風 <3級0.0-5.05.0...FalseFalseFalseTrueNaNNaN0010
5255992019-12-31 23:00:00站點60.0000002019-12-31晴轉多雲0℃~-5℃西風轉南風 <3級0.0-5.05.0...FalseFalseFalseTrueNaNNaN0010

2 rows × 21 columns

【END】

3. 對df的水壓一列構造如下時序特徵

3.1 當前時刻該站點水壓與本月的相同整點時間該站點水壓均值的差,例如當前時刻為2018-05-20 17:00:00,那麼對應需要減去的值為當前月所有17:00:00時間點水壓值的均值

思路

首先計算按月到時刻、站點的均值,然後拼接到主表,最後進行計算

【START】

#對df進行改造,新增月和時刻的列值
df = pd.DataFrame(df_h[['Time','date','站點','壓力','是否有雨','是否有雪']])
df['month'] = df['Time'].dt.month
df['hour'] = df['Time'].dt.hour
df.head()
Timedate站點壓力是否有雨是否有雪monthhour
02018-01-012018-01-01站點40.402750FalseFalse10
12018-01-012018-01-01站點70.214375FalseFalse10
22018-01-012018-01-01站點220.247000FalseFalse10
32018-01-012018-01-01站點210.284250FalseFalse10
42018-01-012018-01-01站點200.292875FalseFalse10
#到月到時段的均值計算
df_month = df.groupby(['month','hour','站點'])['壓力'].mean()
df_month = df_month.reset_index()
df_month.head()
monthhour站點壓力
010站點10.260095
110站點100.259512
210站點110.244476
310站點120.252960
410站點130.259923
#將到月的資料拼接到df,使用值拼接
df = df.merge(df_month, on=['month','hour','站點'],how='left')
df = df.sort_values(by=['站點','hour'],axis=0,ascending=True)
df = df.rename(columns={'壓力_x':'壓力','壓力_y':'平均壓力'})
df[(df['站點']=='站點1')&df['hour']==1].head(3)
Timedate站點壓力是否有雨是否有雪monthhour平均壓力
219092018-01-01 01:00:002018-01-01站點10.292000FalseFalse110.266966
219392018-01-02 01:00:002018-01-02站點10.291625FalseFalse110.266966
219692018-01-03 01:00:002018-01-03站點10.296500FalseTrue110.266966

【END】

3.2 當前時刻所在周的週末該站點水壓均值與工作日水壓均值之差

思路

首先找到站點的週末和工作日,然受計算週末和工作日的均值,最後再按照站點、年、月、周進行彙總

【START】

#增加年、周、工作日維度
df['year'] = df['Time'].dt.year
df['week'] = df['Time'].dt.isocalendar().week
df['day_week'] = df['Time'].dt.dayofweek
df.head(2)
Timedate站點壓力是否有雨是否有雪monthhour平均壓力yearweekday_week
92018-01-012018-01-01站點10.288625FalseFalse100.260095201810
392018-01-022018-01-02站點10.286750FalseFalse100.260095201811
#週末的水壓均值
df_m = df[df['day_week'].isin([5,6])]
df_m2 = df_m.groupby(['站點','year','month','week'])['壓力'].mean()
df_m2 = df_m2.reset_index()
df_m2 = df_m2.rename(columns={'壓力':'週末平均壓力'})
df_m2.head(2)
站點yearmonthweek週末平均壓力
0站點12018110.251711
1站點12018120.248945
#工作日的水壓均值
df_w = df[df['day_week'].isin([0,1,2,3,4])]
df_w2 = df_w.groupby(['站點','year','month','week'])['壓力'].mean()
df_w2 = df_w2.reset_index()
df_w2 = df_w2.rename(columns={'壓力':'工作日平均壓力'})
df_w2.head(2)
站點yearmonthweek工作日平均壓力
0站點12018110.253222
1站點12018120.252750
#拼接資料
df = df.merge(df_m2, on=['站點','year','month','week'],how='left')
df = df.merge(df_w2, on=['站點','year','month','week'],how='left')
#做差值
df['週末與工作日壓力差值'] = df['週末平均壓力'] - df['工作日平均壓力']
df.tail(2)
Timedate站點壓力是否有雨是否有雪monthhour平均壓力yearweekday_week週末平均壓力工作日平均壓力週末與工作日壓力差值
5255982019-12-30 23:00:002019-12-30站點90.225375FalseFalse12230.247349201910NaN0.218828NaN
5255992019-12-31 23:00:002019-12-31站點90.201375FalseFalse12230.247349201911NaN0.218828NaN

【END】

3.3 當前時刻向前7日內,該站點水壓的均值、標準差、0.95分位數、下雨天數與下雪天數的總和

思路

我理解這一問求得是到日的結果,不到時刻對應的結果,按照每個不同的站點,使用rolling移動求出相對應的值,這裡僅實現了均值,其他的可以參照這個方法實現,但是使用rolling會將當天也算在7天內,這是一個bug點

【START】

s = df.copy()
#得到到單日的均值
f = pd.DataFrame(s.groupby(['date','站點'])['壓力'].mean())
f = f.reset_index()
#建立站點的序列,以便下面的迴圈
z = pd.Series(s['站點'].unique())
for i in z:
#給定到站點
    s = f[f['站點']==i]
#要使用rolling,所以欄位僅為日期和壓力
    s = s[['date','壓力']]
#對date進行一個排序
    s = s.sort_values(by='date')
#設定索引
    s1 = s.set_index('date')
#rolling取7天均值
    r = s1.rolling(window=7)
    r1 = r.mean()
#將站點的值拼入r1中
    m = pd.DataFrame([i]*r1.shape[0],index=s['date'].to_list(),columns=['站點'])
    n = pd.concat([r1,m],1)
#得到最終結果
    result = pd.concat([result,n])
result[result['站點']=='站點2']
壓力站點
2018-01-01NaN站點2
2018-01-02NaN站點2
2018-01-03NaN站點2
2018-01-04NaN站點2
2018-01-05NaN站點2
.........
2019-12-270.335159站點2
2019-12-280.335098站點2
2019-12-290.334743站點2
2019-12-300.335152站點2
2019-12-310.335009站點2

2920 rows × 2 columns

【END】

3.4 當前時刻向前7日內,該站點同一整點時間水壓的均值、標準差、0.95分位數

思路

依照上面的方法,我們多加一個時刻的引數即可

【START】

s = df.copy()
#得到到單日的均值
f = s[['Time','hour','站點','壓力']]
#建立站點的序列,以便下面的迴圈
z = pd.Series(s['站點'].unique())
t = pd.Series(s['hour'].unique())
for i in z:
    for j in t:
#給定到站點
        s = f[f['站點']==i]
#要使用rolling,所以欄位僅為日期和壓力
        s = s[s['hour']==j]
        s = s[['Time','壓力']]
#對date進行一個排序
        s = s.sort_values(by='Time')
#設定索引
        s1 = s.set_index('Time')
#rolling取7天均值
        r = s1.rolling(window=7)
        r1 = r.mean()
#將站點的值拼入r1中
        m = pd.DataFrame([i]*r1.shape[0],index=s['Time'].to_list(),columns=['站點'])
        n = pd.concat([r1,m],1)
#得到最終結果
        result = pd.concat([result,n])
result[result['站點']=='站點2']
壓力站點
2018-01-01 00:00:00NaN站點2
2018-01-02 00:00:00NaN站點2
2018-01-03 00:00:00NaN站點2
2018-01-04 00:00:00NaN站點2
2018-01-05 00:00:00NaN站點2
.........
2019-12-27 23:00:000.338964站點2
2019-12-28 23:00:000.339286站點2
2019-12-29 23:00:000.339982站點2
2019-12-30 23:00:000.341054站點2
2019-12-31 23:00:000.339714站點2

20440 rows × 2 columns

3.5 當前時刻所在日的該站點水壓最高值與最低值出現時刻的時間差

思路

先求出當前日的水壓最高點和最低點時刻,然後再算時間差

【START】

#找到水壓的最高點,先通過groupby找到最高點的值,然後再通過merge的inner找到最高點的時段
df5 = df_e.copy()
df1 = df5.groupby(['站點','date'])['壓力'].max()
#這裡出現了一個問題,最大值和最小值存在多條記錄的情況,所以選擇在對Time取最大值
df_n = df5.merge(df1,on=['站點','date','壓力'],how='inner')
df_n = pd.DataFrame(df_n.groupby(['站點','date'])['Time'].max())
df_max = df_n.reset_index()
df_max = df_max.rename(columns={'Time':'max_time'})
#找到水壓的最高點,先通過groupby找到最高點的值,然後再通過merge的inner找到最高點的時段
df2 = df5.groupby(['站點','date'])['壓力'].min()
df_n = df5.merge(df2,on=['站點','date','壓力'],how='inner')
#這裡最小值存在多值的問題選擇最小值
df_n = pd.DataFrame(df_n.groupby(['站點','date'])['Time'].min())
df_min = df_n.reset_index()
df_min = df_min.rename(columns={'Time':'min_time'})
#通過date和站點將最大值和最小值拼接
df_f = df_max.merge(df_min, on=['date','站點'],how='outer')
df_f['time_diff'] = df_f['max_time'] -df_f['min_time'] 
df_f.sort_values(by=['date'])
df_f = df_f[['date','站點','time_diff']]
df_f.head(2)
date站點time_diff
02018-01-01站點1-1 days +18:00:00
12018-01-02站點1-1 days +18:00:00

【END】

總結

在題目2中遇到的最大的問題是,當寫了很多條賦值語句的時候,命名如果不具有代表性,很難清晰的知道之前的含義,在之後的學習中一定要規避這個問題,儘量將名稱認真的取名。

整個做題的過程中,大部分的思維方式都是基於表格運算的思維方式,這個方式可以解決問題,但是可能並不是最優的方案,之後還需要更多的去了解python內的知識,轉變自己的思維方式。

最後,要養成寫備註的習慣!!!