下面给出了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 Inference float precision type resnet50 resnet50 model
average inference time : 13.426570892333984 ms
请把日志结果进行整理,变换成如下状态,model_i用相应模型名称填充,按照字母顺序排序,数值保留三位小数:
#略去前10行和后2行 不设置第一行数据为col值 引擎使用python
df = pd.read_table('./data/mission04/benchmark.txt',skiprows=10,skipfooter=2,header=None,engine='python')
df
def my_func(x):
list1 = x.iloc[1].split(' ')
list2 = x.iloc[-1].split(' ')
return pd.Series([list2[0],list1[1],float(list2[-2]),list1[2]],index=['model_name','data_type','time','state'])
#把df的每两行合并到一起,并用my_func方法提取4个参数并将time小数点后保留三位
df_demo = pd.concat([df[0::2].reset_index(),df[1::2].reset_index()],axis=1).apply(my_func,axis=1).round({
'time': 3})
#进行长宽表转换
res = df_demo.pivot(index='model_name',columns=['data_type','state'],values='time')
#进行多级列索引合并
res.columns = res.columns.map(lambda x:(x[0]+'_'+x[1]))
#按要求排列列索引顺序
res = res[['Training_half','Training_float','Training_double','Inference_half','Inference_float','Inference_double']]
res.shape
(32, 6)
res
df1和df2中分别给出了18年和19年各个站点的数据,其中列中的H0至H23分别代表当天0点至23点
df3中记录了18-19年的每日该地区的天气情况
请完成如下的任务:
def process_df(my_df):
df_demo = my_df.melt(id_vars=['Time','MeasName'],value_vars=df1.columns[2:],var_name='小时',value_name='压力')
df_demo.Time = pd.to_datetime(df_demo.Time) + pd.to_timedelta(df_demo['小时'].apply(lambda x:x[1:]+'H'))
df_demo.MeasName = df_demo.MeasName.apply(lambda x:int(x[2:]))
df_demo.drop('小时',axis=1,inplace=True)
return df_demo.sort_values(['Time','MeasName'])
df1 = pd.read_csv('./data/mission05/yali18.csv')
df2 = pd.read_csv('./data/mission05/yali19.csv')
df = pd.concat([process_df(df1),process_df(df2)])
df.reset_index(drop=True,inplace=True)
df.rename(columns = {
'MeasName':'站点'},inplace=True)
df.set_index('Time',inplace=True)
df
df3 = pd.read_csv('./data/mission05/qx1819.csv')
df3
def my_func(x):
list2 = x[2].replace(' ','').split('~')
a1 = int(list2[0][:-1]) if list2[0] not in '℃C' else 0
a2 = int(list2[1][:-1]) if list2[1] not in '℃C' else 0
a1 = a2 if a1 < a2 else a1
return pd.Series([x[0],a1,a2,a1-a2],index=['日期','最高温','最低温','温差'])
df3.apply(my_func,axis=1)
def my_func(x):
return pd.Series(['沙' in x[1],'雾' in x[1],'雨' in x[1],'雪' in x[1],'晴天' in x[1]],index=['是否有沙暴','是否有雾','是否有雨','是否有雪','是否为晴天'])
df3.apply(my_func,axis=1)
对不同的雨雪情况进行观察:
def my_func(x):
if '雪' in x:
return x
snow_list = list(df_weather.apply(my_func).drop_duplicates())[1:]
snow_list
['阴转小雪',
'多云转小到中雪',
'雨夹雪转阴',
'多云转小雪',
'阴转雨夹雪',
'雨夹雪转多云',
'大雪转多云',
'阴转中到大雪',
'小雪转晴',
'扬沙转雨夹雪',
'雨夹雪转大雪',
'雾转雨夹雪']
def my_func(x):
if '雨' in x:
return x
rain_list = list(df_weather.apply(my_func).drop_duplicates())[1:]
rain_list
['雨夹雪转阴',
'阴转雨夹雪',
'小雨转阴',
'多云转小雨',
'阴转小雨',
'中雨转小雨',
'多云转雷阵雨',
'雨夹雪转多云',
'小雨',
'多云转中到大雨',
'阴转阵雨',
'小雨转中雨',
'阴转雷阵雨',
'多云转小到中雨',
'阴转小到中雨',
'大雨转小雨',
'阴转中雨',
'雷阵雨',
'小雨转雷阵雨',
'雷阵雨转阴',
'雷阵雨转多云',
'阴转中到大雨',
'中雨转暴雨',
'小雨转多云',
'阴转大雨',
'中雨转多云',
'多云转阵雨',
'扬沙转雨夹雪',
'雨夹雪转大雪',
'多云转中雨',
'雨转阴',
'小雨转阵雨',
'大雨转多云',
'暴雨转雷阵雨',
'晴转阵雨',
'中雨转阴',
'中雨转雷阵雨',
'暴雨',
'中雨转小到中雨',
'雨转多云',
'晴转小雨',
'雾转小雨',
'雾转雨夹雪']
观察后,将雨雪按照不同类别进行离散分类:
雨的种类 | 等级 |
---|---|
小雨 | 1 |
中雨 | 2 |
大雨 | 3 |
阵雨 | 4 |
暴雨 | 5 |
雨夹雪 | 6 |
雪的种类 | 等级 |
---|---|
小雪 | 1 |
中雪 | 2 |
大雪 | 3 |
雨夹雪 | 4 |
做一个说明,这里考虑到有不同的“转”的情况,比如“小雨转阵雨”,“阴转大雨”等,这里统一以强度最高的类别为主体:
def my_func(x):
def judge(s,type):
dict = snow_dict if type else rain_dict
for x in dict:
if x in s:
return dict[x]
return 0
snow_dict = dict(zip(['小雪','中雪','大雪','雨夹雪'],range(1,5)))
rain_dict = dict(zip(['小雨','中雨','大雨','阵雨','暴雨','雨夹雪'],range(1,7)))
return pd.Series([judge(x[1],1),judge(x[1],0)],index=['雨量等级','雪量等级'])
df_weather_descibe = df3.apply(my_func,axis=1)
df_weather_descibe
def my_func(x):
def returnWindCode(s):
res = [pd.NA,pd.NA]
if '东' in s:
res[0] = 1
if '西' in s:
res[0] = 0
if '南' in s:
res[1] = 1
if '北' in s:
res[1] = 0
return res
#list代表风向
list = x[-1].split(' ')
#提前补全
if '转' not in list[0]:
list[0] += '转'
#list1为风向列表,可能为空
list1 = list[0].split('转')
res = []
for x in list1:
res += returnWindCode(x)
return pd.Series(res,index=['前风 东1西0','前风 南1北0','后风 东1西0','后风 南1北0'])
df3.apply(my_func,axis=1).head(10)
由于df与df3合并相当于是多对一合并,所以这里首选merge方法
将上面4类额外数据进行统一合并操作:
先进行汇总:
def my_func(x):
def getWeather():
typeList = ['沙','雾','雨','雪','晴天']
return [1 if item in x[1] else 0 for item in typeList]
def getTemp():
list2 = x[2].replace(' ','').split('~')
a1 = int(list2[0][:-1]) if list2[0] not in '℃C' else 0
a2 = int(list2[1][:-1]) if list2[1] not in '℃C' else 0
a1 = a2 if a1 < a2 else a1
return [a1,a2,a1-a2]
def getWeatherDes():
def judge(s,type):
dict = snow_dict if type else rain_dict
for x in dict:
if x in s:
return dict[x]
return 0
snow_dict = dict(zip(['小雪','中雪','大雪','雨夹雪'],range(1,5)))
rain_dict = dict(zip(['小雨','中雨','大雨','阵雨','暴雨','雨夹雪'],range(1,7)))
return [judge(x[1],1),judge(x[1],0)]
def getWindType():
def returnWindCode(s):
res = [pd.NA,pd.NA]
if '东' in s:
res[0] = 1
elif '西' in s:
res[0] = 0
if '南' in s:
res[1] = 1
elif '北' in s:
res[1] = 0
return res
#list代表风向
list = x[-1].split(' ')
#提前补全
if '转' not in list[0]:
list[0] += '转'
#list1为风向列表,可能为空
list1 = list[0].split('转')
res = []
for item in list1:
res += returnWindCode(item)
return res
index = ['日期','最高温','最低温','温差','是否有沙暴','是否有雾','是否有雨','是否有雪','是否为晴天','雪量等级','雨量等级','前 东1西0','前 南1北0','后 东1西0','后 南1北0']
return pd.Series([pd.to_datetime(x[0])]+getTemp()+getWeather()+getWeatherDes()+getWindType(),index=index)
df_total = df3.apply(my_func,axis=1)
df_total
然后进行merge:
df_demo = df
df_demo['日期'] = pd.to_datetime(df.index.date)
df_demo = df_demo.reset_index().merge(df_total,on='日期',how='left',validate='m:1').set_index('Time').drop('日期',axis=1)
df_demo
注意这里需要对日期列转成时序类型,并且要将merge方法中的validate参数设置为‘m:1’,否则右边会产生很多空值。而且因为合并后不保留行索引,所以在合并之前要把df_demo的行索引重置,在合并后删掉‘日期’列,效果如下:
首先建立一个根据年、月、小时、站点分组的分组对象,然后求得压力均值,最后将行索引进行合并,存入df_table中:
def concatFourNum(a,b,c,d):
return str(a)+'-'+str(b)+'-'+str(c)+'-'+str(d)
df_table = df.groupby([df.index.year,df.index.month,df.index.hour,'站点'])['压力'].mean()
df_table.index = df_table.index.map(lambda x:concatFourNum(x[0],x[1],x[2],x[3]))
df_table = df_table.to_frame().reset_index()
df_table
然后新建一个df的copy:df_demo,遍历每行建立与df_table的index列保持一致的列:
df_demo = df.copy()
df_demo['index'] = pd.to_datetime(df_demo.index)
df_demo['index'] = df_demo.apply(lambda x:concatFourNum(x[-1].year,x[-1].month,x[-1].hour,x[0]),axis=1)
df_demo
最后将两张表进行合并,合并后的效果为:
df_res = df_demo.merge(df_table,on='index',validate='m:1',how='left')
df_res
此时压力_x代表当前的压力,压力_y代表题目要求的当月相同整点的压力均值,相减即可得到结果:
res = df_res['压力_x'] - df_res['压力_y']
res
0 0.014988
1 0.000835
2 0.000738
3 -0.015472
4 0.001440
...
525595 -0.004948
525596 -0.021786
525597 -0.009992
525598 -0.012544
525599 -0.011625
Length: 525600, dtype: float64
首先增加额外信息列辅助判断,分别为站点+当前年份+周数,以及是否为周内:
df_demo = df.copy().reset_index()
# df_demo['weekInfo'] =
df_demo['weekInfo'] = df_demo.apply(lambda x:str(x[1])+'-'+str(x[0].year)+'-'+str(x[0].weekofyear),axis=1)
df_demo['isWeekdays'] = df_demo.apply(lambda x:x[0].dayofweek < 5,axis=1)
df_demo
然后按weekInfo进行分组,利用isWeekdays列分别求均值:
s_wdays = df_demo[df_demo.isWeekdays].groupby('weekInfo')['压力'].mean()
s_wdays
weekInfo
1-2018-1 0.247120
1-2018-10 0.250056
1-2018-11 0.246278
1-2018-12 0.240869
1-2018-13 0.243756
...
9-2019-52 0.210806
9-2019-6 0.265816
9-2019-7 0.239919
9-2019-8 0.250313
9-2019-9 0.254747
Name: 压力, Length: 3120, dtype: float64
s_wends = df_demo[~df_demo.isWeekdays].groupby('weekInfo')['压力'].mean()
s_wends
weekInfo
1-2018-1 0.251711
1-2018-10 0.251602
1-2018-11 0.237789
1-2018-12 0.242266
1-2018-13 0.241422
...
9-2019-52 0.204203
9-2019-6 0.245734
9-2019-7 0.237219
9-2019-8 0.243523
9-2019-9 0.245055
Name: 压力, Length: 3120, dtype: float64
然后相减后转换成df类型准备拼接:
res = (s_wdays - s_wends).to_frame().reset_index()
res
最后利用df_demo进行拼接:
df_demo.merge(res,on='weekInfo',validate='m:1',how='left').set_index('Time')
压力_y即为所求。
这块也有一点点小问题,不是所有的日期所属的周都是按所在年计算:
pd.Timestamp('2021-01-01').weekofyear
53
pd.Timestamp('2019-12-31').weekofyear
1
解决思路:研究一下日历中不同日子所属周相对于年的关系,然后在上面生成weekIndex的代码中进行额外的逻辑判断。
df_demoda代表2问中求得的df
gb = df_demo.groupby('站点')
gb.rolling('7D')['压力'].mean()
站点 Time
1 2018-01-01 00:00:00 0.288625
2018-01-01 01:00:00 0.290313
2018-01-01 02:00:00 0.290375
2018-01-01 03:00:00 0.292656
2018-01-01 04:00:00 0.294175
...
30 2019-12-31 19:00:00 0.276701
2019-12-31 20:00:00 0.276730
2019-12-31 21:00:00 0.276777
2019-12-31 22:00:00 0.276824
2019-12-31 23:00:00 0.276750
Name: 压力, Length: 525600, dtype: float64
gb.rolling('7D')['压力'].std()
站点 Time
1 2018-01-01 00:00:00 NaN
2018-01-01 01:00:00 0.002386
2018-01-01 02:00:00 0.001691
2018-01-01 03:00:00 0.004767
2018-01-01 04:00:00 0.005346
...
30 2019-12-31 19:00:00 0.027159
2019-12-31 20:00:00 0.027153
2019-12-31 21:00:00 0.027120
2019-12-31 22:00:00 0.027075
2019-12-31 23:00:00 0.027063
Name: 压力, Length: 525600, dtype: float64
gb.rolling('7D')['压力'].quantile(0.95)
站点 Time
1 2018-01-01 00:00:00 0.288625
2018-01-01 01:00:00 0.291831
2018-01-01 02:00:00 0.291850
2018-01-01 03:00:00 0.298375
2018-01-01 04:00:00 0.300100
...
30 2019-12-31 19:00:00 0.319988
2019-12-31 20:00:00 0.319988
2019-12-31 21:00:00 0.319988
2019-12-31 22:00:00 0.319988
2019-12-31 23:00:00 0.319988
Name: 压力, Length: 525600, dtype: float64
求7天内下雨,下雪天数:
df_res = df_demo.copy()
df_res['Date'] = pd.to_datetime(pd.to_datetime(df_res.index).date)
df_res = df_res[['站点','是否有雨','是否有雪','Date']]
df_res = df_res.groupby(['站点','Date']).agg(lambda x:1 if sum(x) > 0 else 0)
df_res.reset_index('站点').groupby('站点')[['是否有雨','是否有雪']].rolling('7D').sum().rename(columns={
'是否有雨':'7天内有雨天数','是否有雪':'7天内有雪天数'})
用主数据表进行merge合并。
先求同一整点的水压的三个系数,然后再进行滑动窗口。
gb = df.groupby([df.index.year,df.index.month,df.index.hour,'站点']).rolling('7D')['压力']
gb.mean()
Time Time Time 站点
2018 1 0 1 0.288625
1 0.287688
1 0.289125
1 0.289563
1 0.288550
...
2019 12 23 30 0.286714
30 0.283821
30 0.284839
30 0.284679
30 0.282911
Name: 压力, Length: 525600, dtype: float64
gb.std()
Time Time Time 站点
2018 1 0 1 NaN
1 0.001326
1 0.002660
1 0.002342
1 0.003040
...
2019 12 23 30 0.006524
30 0.007718
30 0.007381
30 0.007127
30 0.007878
Name: 压力, Length: 525600, dtype: float64
gb.quantile(0.95)
Time Time Time 站点
2018 1 0 1 0.288625
1 0.288531
1 0.291663
1 0.291831
1 0.291775
...
2019 12 23 30 0.294450
30 0.293550
30 0.293550
30 0.292763
30 0.292763
Name: 压力, Length: 525600, dtype: float64
待修改的地方,虽然长度保持一致,但是行索引已经不同,需要修改。
新增主键列index:
def concatFourNum(a,b,c,d):
return str(a)+'-'+str(b)+'-'+str(c)+'-'+str(d)
df_demo = df.copy()
df_demo['index'] = pd.to_datetime(df_demo.index)
df_demo['index'] = df_demo.apply(lambda x:concatFourNum(x[-1].year,x[-1].month,x[-1].day,x[0]),axis=1)
df_demo = df_demo.reset_index()
df_demo
计算每个站点每日的最大压力和最小压力之间的时间差:
res = df.groupby([pd.to_datetime(df.index.date),'站点']).idxmax() - df.groupby([pd.to_datetime(df.index.date),'站点']).idxmin()
res.index = res.index.map(lambda x:concatFourNum(x[0].year,x[0].month,x[0].day,x[1]))
res = res.reset_index()
res
res = df_demo.merge(res,how='left',on='index',validate='m:1')
res = res.set_index('Time')[['站点','压力_y']].rename(columns={
'压力_y':'最高值与最低值出现时刻的时间差'})
res
https://zhidao.baidu.com/question/1732599155287606027.html