谈谈感想:20多天的pandas学习今天就结束了,说实话突然内心感觉空落落的,认识了一群有同样目标的同学,而且也完成了自己满勤的愿望。虽然期末大综合没有做完,但是里面的每一步都是自己一步步试出来的。时间紧任务重,但是却觉得异常的充实。在这里感谢DW的老师和助教们,自己学到了很多,成长了很多,希望自己有一天可以进到组织里,和大家一起成长,谢谢!
1. 显卡日志
下面给出了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用相应模型名称填充,按照字母顺序排序,数值保留三位小数:
自己的想法:
- 需要把表变为模型、状态、精度、耗时(正则表达式)
- 长表变宽表(pivot)
# 导入数据 benchmark.txt
df1 = pd.read_table('data/final/benchmark.txt')
df1.tail()
start | |
---|---|
390 | shufflenet_v2_x1_5 model average inference ti... |
391 | Benchmarking Inference double precision type s... |
392 | shufflenet_v2_x2_0 model average inference ti... |
393 | benchmark end : 2020/12/24 12:56:47 |
394 | end |
# 使用正则表达式把一行分列
pat1 = 'Benchmarking\s(?P<状态>\w+)\s(?P<精度>\w+)\sprecision type\s(?P<模型>\w+)'
pat2 = '(?P<模型>\w+)\s*model\s*average\s*(?P<状态>\w+)\s*time\s*:\s*(?P<耗时>.*\.+...).*\s*ms'
df1_1 = df1['start'].str.extract(pat1).dropna().reset_index()
df1_2 = df1['start'].str.extract(pat2).dropna().reset_index()
# 查看一下数据
df1_1.head()
index 状态 精度 模型
0 9 Training float mnasnet0_5
1 11 Training float mnasnet0_75
2 13 Training float mnasnet1_0
3 15 Training float mnasnet1_3
4 17 Training float resnet18
df1_2.head()
index 模型 状态 耗时
0 10 mnasnet0_5 train 28.527
1 12 mnasnet0_75 train 34.105
2 14 mnasnet1_0 train 34.313
3 16 mnasnet1_3 train 35.556
4 18 resnet18 train 18.660
# 重命名的原因:报错——columns overlap but no suffix specified: Index(['data1', 'data2'], dtype='object')
# 解决办法:重命名 https://blog.csdn.net/qq_43546676/article/details/98611306
df1_2.columns = ['idx','模型2','状态2','耗时']
df1_3 = df1_1.join(df1_2, how='left') #把第n行和第n+1行合并
df1_3.head()
index 状态 精度 模型 idx 模型2 状态2 耗时
0 9 Training float mnasnet0_5 10 mnasnet0_5 train 28.527
1 11 Training float mnasnet0_75 12 mnasnet0_75 train 34.105
2 13 Training float mnasnet1_0 14 mnasnet1_0 train 34.313
3 15 Training float mnasnet1_3 16 mnasnet1_3 train 35.556
4 17 Training float resnet18 18 resnet18 train 18.660
df1_4 = pd.DataFrame(df1_3, columns = ['模型', '状态','精度','状态2','耗时']).sort_values(by = '模型').reset_index(drop=True)
df1_4[' '] = df1_4['状态2'].str.capitalize() + '_' + df1_4['精度']
df1_4.head()
模型 状态 精度 状态2 耗时
0 densenet121 Inference half inference 19.772 Inference_half
1 densenet121 Inference double inference 144.110 Inference_double
2 densenet121 Training half train 88.976 Train_half
3 densenet121 Training double train 417.206 Train_double
4 densenet121 Training float train 93.357 Train_float
# pivot:长表变宽表
df1_final = df1_4.pivot(index='模型', columns=' ', values='耗时')
# 移动列的位置
df1_final = pd.DataFrame(df1_final, columns = ['Train_half', 'Train_float','Train_double','Inference_half','Inference_float','Inference_double'])
# 去掉索引名字
df1_final.rename_axis(index={'模型':' '}).head()
Train_half | Train_float | Train_double | Inference_half | Inference_float | Inference_double | |
---|---|---|---|---|---|---|
densenet121 | 88.976 | 93.357 | 417.206 | 19.772 | 15.636 | 144.110 |
densenet161 | 144.318 | 136.624 | 1290.286 | 27.554 | 31.750 | 511.176 |
densenet169 | 121.555 | 104.839 | 511.403 | 26.370 | 21.598 | 175.807 |
densenet201 | 118.940 | 129.333 | 654.365 | 33.393 | 26.169 | 223.960 |
mnasnet0_5 | 27.197 | 28.527 | 48.232 | 6.929 | 8.038 | 11.870 |
2. 水压站点的特征工程
df1和df2中分别给出了18年和19年各个站点的数据,其中列中的H0至H23分别代表当天0点至23点;df3中记录了18-19年的每日该地区的天气情况,请完成如下的任务:
import pandas as pd
import numpy as np
df1 = pd.read_csv('data/final/yali18.csv')
df2 = pd.read_csv('data/final/yali19.csv')
df3 = pd.read_csv('data/final/qx1819.csv')
df1.head()
Time | MeasName | H0 | H1 | H2 | H3 | H4 | H5 | H6 | H7 | ... | H14 | H15 | H16 | H17 | H18 | H19 | H20 | H21 | H22 | H23 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 2018-01-01 | 站点4 | 0.402750 | 0.407625 | 0.418125 | 0.425250 | 0.426000 | 0.425250 | 0.417375 | 0.426375 | ... | 0.348750 | 0.359250 | 0.355500 | 0.344250 | 0.352125 | 0.356250 | 0.347250 | 0.343875 | 0.356625 | 0.418875 |
1 | 2018-01-01 | 站点7 | 0.214375 | 0.226750 | 0.232375 | 0.233125 | 0.235000 | 0.232750 | 0.230875 | 0.220000 | ... | 0.187375 | 0.196750 | 0.199750 | 0.192250 | 0.186250 | 0.183250 | 0.177250 | 0.163375 | 0.165250 | 0.199375 |
2 | 2018-01-01 | 站点22 | 0.247000 | 0.248125 | 0.271375 | 0.251125 | 0.272125 | 0.256375 | 0.257125 | 0.242500 | ... | 0.245500 | 0.242875 | 0.238375 | 0.230875 | 0.237250 | 0.236875 | 0.236500 | 0.236500 | 0.241000 | 0.254500 |
3 | 2018-01-01 | 站点21 | 0.284250 | 0.289875 | 0.283500 | 0.281250 | 0.288375 | 0.288750 | 0.285750 | 0.255750 | ... | 0.227625 | 0.238125 | 0.238500 | 0.218625 | 0.207000 | 0.212625 | 0.209250 | 0.189000 | 0.217875 | 0.270000 |
4 | 2018-01-01 | 站点20 | 0.292875 | 0.295875 | 0.305250 | 0.298875 | 0.310125 | 0.300750 | 0.288375 | 0.262500 | ... | 0.247500 | 0.241125 | 0.243375 | 0.232500 | 0.233625 | 0.224250 | 0.219375 | 0.202125 | 0.219375 | 0.286500 |
5 rows × 26 columns
df2.head()
Time | MeasName | H0 | H1 | H2 | H3 | H4 | H5 | H6 | H7 | ... | H14 | H15 | H16 | H17 | H18 | H19 | H20 | H21 | H22 | H23 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 2019-01-01 | 站点4 | 0.342000 | 0.429375 | 0.429000 | 0.440250 | 0.445875 | 0.444750 | 0.417750 | 0.387000 | ... | 0.319875 | 0.326250 | 0.323625 | 0.322500 | 0.309000 | 0.307125 | 0.307125 | 0.307125 | 0.307125 | 0.307125 |
1 | 2019-01-01 | 站点7 | 0.215125 | 0.239500 | 0.257500 | 0.246250 | 0.275125 | 0.264625 | 0.229375 | 0.205375 | ... | 0.180625 | 0.176500 | 0.181375 | 0.155125 | 0.159625 | 0.146125 | 0.144625 | 0.135250 | 0.158875 | 0.184750 |
2 | 2019-01-01 | 站点22 | 0.244750 | 0.248875 | 0.246625 | 0.247375 | 0.247375 | 0.245500 | 0.244000 | 0.239500 | ... | 0.238000 | 0.236125 | 0.235375 | 0.238000 | 0.231250 | 0.232375 | 0.226750 | 0.227875 | 0.236125 | 0.242125 |
3 | 2019-01-01 | 站点21 | 0.228750 | 0.248250 | 0.258750 | 0.252750 | 0.264375 | 0.265875 | 0.237750 | 0.208125 | ... | 0.200625 | 0.202125 | 0.198000 | 0.186750 | 0.185250 | 0.180000 | 0.174750 | 0.177375 | 0.192750 | 0.212625 |
4 | 2019-01-01 | 站点20 | 0.239125 | 0.260500 | 0.269125 | 0.263500 | 0.278125 | 0.279625 | 0.250375 | 0.216625 | ... | 0.212500 | 0.214375 | 0.202000 | 0.199000 | 0.195250 | 0.188500 | 0.187750 | 0.186625 | 0.205000 | 0.225250 |
5 rows × 26 columns
第一问
通过df1和df2构造df,把时间设为索引,第一列为站点编号,第二列为对应时刻的压力大小,排列方式如下(压力数值请用正确的值替换):
第一小问思路:
- 宽表变长表,合并两张表
- H0-H23转化为时间,把日期和时间合并为新的一列作为索引
- 站点n变为n
# 宽表变长表
df_melted1 = df1.melt(id_vars = ['Time', 'MeasName'],
var_name = 'time1',
value_name = '压力')
df_melted2 = df2.melt(id_vars = ['Time', 'MeasName'],
var_name = 'time1',
value_name = '压力')
pat = 'H(\w+)'
pat2 = '站点(\w+)'
# 构造time2:提取'Hn'的'n'
df_melted1['time2'] = df_melted1['time1'].str.extract(pat)
df_melted2['time2'] = df_melted1['time1'].str.extract(pat)
# 构造time3:将提取的n变为n时0分0秒
df_melted1['time3'] = df_melted1['time2'] + '时0分0秒'
df_melted2['time3'] = df_melted2['time2'] + '时0分0秒'
# 构造time4:将Time列和time3列合并 yyyy-mm-dd HH时MM分SS秒
df_melted1['time4'] = df_melted1['Time'] +' '+ df_melted1['time3']
df_melted2['time4'] = df_melted2['Time'] +' '+ df_melted2['time3']
# 构造time:转化为yyyy-mm-dd HH:MM:SS
df_melted1['time'] = pd.to_datetime(df_melted1['time4'],format='%Y-%m-%d %H时%M分%S秒')
df_melted2['time'] = pd.to_datetime(df_melted2['time4'],format='%Y-%m-%d %H时%M分%S秒')
# 构造站点:将站点n的n提取
df_melted1['站点'] = df_melted1['MeasName'].str.extract(pat2).astype('int32')
df_melted2['站点'] = df_melted2['MeasName'].str.extract(pat2).astype('int32')
# 设置time列为索引
df_melted1 = df_melted1.set_index('time')
df_melted2 = df_melted2.set_index('time')
df_melted1 = pd.DataFrame(df_melted1, columns = ['站点','压力']).sort_values(by = ['time','站点'])
df_melted2 = pd.DataFrame(df_melted2, columns = ['站点','压力']).sort_values(by = ['time','站点'])
# 两表合并
df_melted = pd.concat([df_melted1, df_melted2])
df_melted = df_melted.rename_axis(index={'time':''})
第二问
在上一问构造的df基础上,构造下面的特征序列或DataFrame,并把它们逐个拼接到df的右侧
- 当天最高温、最低温和它们的温差
- 当天是否有沙暴、是否有雾、是否有雨、是否有雪、是否为晴天
- 选择一种合适的方法度量雨量/下雪量的大小(构造两个序列分别表示二者大小)
- 限制只用4列,对风向进行0-1编码(只考虑风向,不考虑大小)
# 先看一下df3
df3.head()
日期 天气 气温 风向
0 2018-01-01 多云 1C~-4C 东南风 微风
1 2018-01-02 阴转多云 8C~0C 东北风 3-4级
2 2018-01-03 阴转小雪 1C~-1C 东北风 4-5级转4-5级
3 2018-01-04 阴 0C~-4C 东北风转北风 3-4级转3-4级
4 2018-01-05 阴转多云 3C~-4C 西风转北风 3-4级转3-4级
第二小问思路:
- 更改日期
- 拆分出最高气温,最低气温,气温差
- 匹配两张表
- 判断天气情况
备注:做的时候想的挺简单的,越做坑越多(比如说存在缺失值,最高温度和最低温度反了)
# 警告:<ipython-input-34-9cd24262a724>:1: FutureWarning: Columnar iteration over characters will be deprecated in future releases. df3['最高温度'], df3['最低温度'] = df3['气温'].str.split('~', 1).str
import warnings
warnings.filterwarnings("ignore")
# https://blog.csdn.net/huoyongliang/article/details/83145913 查到的办法
# 拆出最高温度和最低温度,此时还不是数字
df3['最高温度'], df3['最低温度'] = df3['气温'].str.split('~', 1).str
# 温度变为数字(但是现在格式还未转化为int,因为有缺失值报错)
df3['最高温度1'] = df3['最高温度'].str.extract('(-*\w+)(℃|C)\s*')[0]
df3['最低温度1'] = df3['最低温度'].str.extract('(-*\w+)(℃|C)\s*')[0]
# 要剔除空值,报错:ValueError: cannot convert float NaN to integer
df3_1 = df3.dropna(how = 'any', subset = ['最高温度1', '最低温度1']) # 729行数据变727
df3_1['温差'] = df3_1['最高温度1'].astype('int32') - df3_1['最低温度1'].astype('int32')
# 还有一行最高和最低温度反着的(心里飘过一群羊驼)
df3_1[df3_1['温差']<0]
日期 天气 气温 风向 最高温度 最低温度 最高温度1 最低温度1 温差
408 2019-02-14 阴转小雪 -1℃~0℃ 东北风转南风 3-4级转3-4级 -1℃ 0℃ -1 0 -1
# 处理最高温度和最低温度反着的数据(后面优化)
df3_1.loc[408,'最高温度1'] = 0
df3_1.loc[408,'最低温度1'] = -1
df3_1.loc[408,'温差'] = 1
df3_1[df3_1['温差']<0] #验证一下数据已经没有问题了
到现在刚处理完df3的温度部分,裂开……下面开始处理第一问的 df_melted
df_melt = df_melted.reset_index()
df_melt.columns = ['time','站点','压力']
df_melt['日期'] = df_melt['time'].dt.date
df_melt.head()
# 不转换格式匹配不出来
df3_1['日期'] = pd.to_datetime(df3_1['日期'],format='%Y-%m-%d')
df_melt['日期'] = pd.to_datetime(df_melt['日期'],format='%Y-%m-%d')
df_melt.merge(df3_1, on='日期', how='left')
(后面的内容之后再补充)