编程实践(Pandas)期末综合练习

谈谈感想: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
390shufflenet_v2_x1_5 model average inference ti...
391Benchmarking Inference double precision type s...
392shufflenet_v2_x2_0 model average inference ti...
393benchmark end : 2020/12/24 12:56:47
394end
# 使用正则表达式把一行分列
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_halfTrain_floatTrain_doubleInference_halfInference_floatInference_double
densenet12188.97693.357417.20619.77215.636144.110
densenet161144.318136.6241290.28627.55431.750511.176
densenet169121.555104.839511.40326.37021.598175.807
densenet201118.940129.333654.36533.39326.169223.960
mnasnet0_527.19728.52748.2326.9298.03811.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()
TimeMeasNameH0H1H2H3H4H5H6H7...H14H15H16H17H18H19H20H21H22H23
02018-01-01站点40.4027500.4076250.4181250.4252500.4260000.4252500.4173750.426375...0.3487500.3592500.3555000.3442500.3521250.3562500.3472500.3438750.3566250.418875
12018-01-01站点70.2143750.2267500.2323750.2331250.2350000.2327500.2308750.220000...0.1873750.1967500.1997500.1922500.1862500.1832500.1772500.1633750.1652500.199375
22018-01-01站点220.2470000.2481250.2713750.2511250.2721250.2563750.2571250.242500...0.2455000.2428750.2383750.2308750.2372500.2368750.2365000.2365000.2410000.254500
32018-01-01站点210.2842500.2898750.2835000.2812500.2883750.2887500.2857500.255750...0.2276250.2381250.2385000.2186250.2070000.2126250.2092500.1890000.2178750.270000
42018-01-01站点200.2928750.2958750.3052500.2988750.3101250.3007500.2883750.262500...0.2475000.2411250.2433750.2325000.2336250.2242500.2193750.2021250.2193750.286500

5 rows × 26 columns

df2.head()
TimeMeasNameH0H1H2H3H4H5H6H7...H14H15H16H17H18H19H20H21H22H23
02019-01-01站点40.3420000.4293750.4290000.4402500.4458750.4447500.4177500.387000...0.3198750.3262500.3236250.3225000.3090000.3071250.3071250.3071250.3071250.307125
12019-01-01站点70.2151250.2395000.2575000.2462500.2751250.2646250.2293750.205375...0.1806250.1765000.1813750.1551250.1596250.1461250.1446250.1352500.1588750.184750
22019-01-01站点220.2447500.2488750.2466250.2473750.2473750.2455000.2440000.239500...0.2380000.2361250.2353750.2380000.2312500.2323750.2267500.2278750.2361250.242125
32019-01-01站点210.2287500.2482500.2587500.2527500.2643750.2658750.2377500.208125...0.2006250.2021250.1980000.1867500.1852500.1800000.1747500.1773750.1927500.212625
42019-01-01站点200.2391250.2605000.2691250.2635000.2781250.2796250.2503750.216625...0.2125000.2143750.2020000.1990000.1952500.1885000.1877500.1866250.2050000.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	阴转多云	8C0C	东北风 3-42	2018-01-03	阴转小雪	1C-1C	东北风 4-5级转4-53	2018-01-040C-4C	东北风转北风 3-4级转3-44	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-10-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')

在这里插入图片描述
(后面的内容之后再补充)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值