pandas-task11-综合练习.md

文章目录

  • 【任务一】显卡日志
    • 解决思路
      • 1.文本数据正则抽取,去缺失值,列重命名,重置index
      • 2.横向连接两表-concat
      • 3.去除重复列,精度保留三位小数
      • 4.表的变型 长变宽pivot
      • 5.索引变型及多级索引的压缩
      • 6.调整,按模型名称排序
  • 【任务二】水压站点的特征工程
    • 问题1:
    • 解决思路
      • 1.表变型 宽表变长表-melt
      • 2.修改格式-文本正则,时间格式化
      • 3.设置时间为index
      • 4.纵向合并两个表 concat
    • 问题2:
    • 解决思路
      • 1.取df的时间年月日构成date列
      • 2.正则表达式获取最高温和最低温
      • 3.获取温差
      • 4.关系连接 merge
    • 问题3:
    • 解决思路
      • 1.contains
      • 2.match+$
    • 问题4:
    • 解决思路:
      • 1.cat+contains获取所有含雨的天气类型
      • 2.zip组成雨类型的字典
      • 3.天气匹配下雨等级字典表
    • 问题5:
    • 解决思路:
      • 1.contains
      • 其他思路:
    • 剩余练习

【任务一】显卡日志

下面给出了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用相应模型名称填充,按照字母顺序排序,数值保留三位小数:
pandas-task11-综合练习.md_第1张图片

解决思路

1.文本数据正则抽取,去缺失值,列重命名,重置index

根据数据特点,可以看出需要统计的数据都是一个格式,首先使用正则表达式抽取需要的第一行和第二行信息,并将抽取的信息重命名。这里也可以直接使用子组的命名达到重命名列的效果,下面演示的是第一种方法:

df=pd.read_table('data/benchmark.txt', header=None)
pat1='Benchmarking (\w+) (\w+) precision type (\w+)'
pat2='(\w+)  model average (\w+) time :  (.+) ms'
bench_info=df[0].str.extract(pat1).rename(columns={
     0:'type_x',
								 1:'precision',
								 2:'model_name_x'}).dropna()
								 .reset_index(drop=True)

使用子组的方法重命名列名:

df=pd.read_table('data/benchmark.txt', header=None)
pat1='Benchmarking (?P\w+) (?P\w+) precision type (?P\w+)'
pat2='(?P\w+)  model average (?P\w+) time :  (?P.+) ms'
bench_info=df[0].str.extract(pat1).dropna()
				.reset_index(drop=True)
bench_info

下面是对应的第一行信息,去掉了缺失值,以及重置了index,命名为bench_info:
pandas-task11-综合练习.md_第2张图片
类似地可以得到每个模型地第二个行信心,同样处理,命名为model_info,可以看到这里获取地两个信息数量相同,是一一对应的:

model_info=df[0].str.extract(pat2).rename(
							columns={
     0:'model_name_y', 
							1:'type_y',2:'time_val'}).dropna()
							.reset_index(drop=True)

pandas-task11-综合练习.md_第3张图片

2.横向连接两表-concat

将两个表合并成一个表:

temp=pd.concat([bench_info,model_info],axis=1).reset_index(
												drop=True)
temp

pandas-task11-综合练习.md_第4张图片

注意这里不能用merge或者merge_table,merge是因为不唯一,merge_table用了的话会有很多重复数据。这里之前花了很多时间定位问题。

3.去除重复列,精度保留三位小数

temp=temp[['model_name_x','type_y','precision',
           'time_val']].rename(columns={
     'model_name_x':'model','type_y':'type'})
temp.time_val=pd.to_numeric(temp.time_val, 
                            errors='coerce').round(3)
temp

pandas-task11-综合练习.md_第5张图片

4.表的变型 长变宽pivot

长表变宽表,使用pivot

#变型 长变宽
temp=temp.pivot(index=['model','type'], 
			columns='precision', values='time_val')
temp

pandas-task11-综合练习.md_第6张图片

5.索引变型及多级索引的压缩

下面使用unstack,将最里面一层index进行行列转换:

temp=temp.unstack()
temp.head()

pandas-task11-综合练习.md_第7张图片

使用map函数对多级index进行组合变型:

temp.columns=temp.columns.map(lambda x:(x[1]+'_'+x[0]))
temp=temp.reset_index()
temp.head()

pandas-task11-综合练习.md_第8张图片

6.调整,按模型名称排序

最后进行行和列的重新排序以达到最好的显示效果,这里对列试了一下sort_index,但是model列会被放到中间,最终还是选择了最基础的方法。对行以模型名称按照字母顺序排序:

# temp.sort_index(axis=1,ascending=False)
temp=temp[['model','train_half','train_float',
           'train_double','inference_half',
           'inference_float','inference_double']]
temp=temp.sort_values('model',ascending=True)
temp.head()

pandas-task11-综合练习.md_第9张图片

【任务二】水压站点的特征工程

df1和df2中分别给出了18年和19年各个站点的数据,其中列中的H0至H23分别代表当天0点至23点;df3中记录了18-19年的每日该地区的天气情况,请完成如下的任务:

import pandas as pd
import numpy as np
df1 = pd.read_csv('yali18.csv')
df2 = pd.read_csv('yali19.csv')
df3 = pd.read_csv('qx1819.csv')

问题1:

  • 通过df1和df2构造df,把时间设为索引,第一列为站点编号,第二列为对应时刻的压力大小,排列方式如下(压力数值请用正确的值替换):
                       站点    压力
2018-01-01 00:00:00       1    1.0
2018-01-01 00:00:00       2    1.0
...                     ...    ...
2018-01-01 00:00:00      30    1.0
2018-01-01 01:00:00       1    1.0
2018-01-01 01:00:00       2    1.0
...                     ...    ...
2019-12-31 23:00:00      30    1.0

解决思路

原表样式 df2为19年水站数据,
df118年数据,与之类似:
pandas-task11-综合练习.md_第10张图片

1.表变型 宽表变长表-melt

#宽表变长表
H_list=['H'+str(i) for i in range(12)]
df1=df1.melt(id_vars =['Time','MeasName'],
             value_vars =H_list,var_name = 'H',
             value_name = '压力')
df1

pandas-task11-综合练习.md_第11张图片
这里后来检查的时候发现最终少了一半数据,定位问题发现是这里时间H0-H23一共24h,我给写成了12个小时,修改后:

#宽表变长表
H_list=['H'+str(i) for i in range(24)]
df1=df1.melt(id_vars =['Time','MeasName'],
             value_vars =H_list,var_name = 'H',
             value_name = '压力')
df1

pandas-task11-综合练习.md_第12张图片

2.修改格式-文本正则,时间格式化

# 修改对应格式 str正则
df1.MeasName=df1.MeasName.str.replace('站点','')
df1.H=df1.H.str.replace('H','')
df1.Time=df1.Time+'-'+df1.H
df1.Time=pd.to_datetime(df1.Time,format='%Y-%m-%d-%H')
df1=df1.rename(columns={
     'MeasName':'站点'}).drop(columns='H')
df1

pandas-task11-综合练习.md_第13张图片

3.设置时间为index

df1=df1.rename(columns={
     'Time':' '}).set_index(' ')
df1

pandas-task11-综合练习.md_第14张图片
df2按照完全一致的方式处理,处理后样式:
pandas-task11-综合练习.md_第15张图片

4.纵向合并两个表 concat

df=pd.concat([df1,df2],axis=0)
df

pandas-task11-综合练习.md_第16张图片

问题2:

表3为当天的天气情况:
pandas-task11-综合练习.md_第17张图片

  • 在上一问构造的df基础上,构造下面的特征序列或DataFrame,并把它们逐个拼接到df的右侧
    • 当天最高温、最低温和它们的温差

解决思路

1.取df的时间年月日构成date列

df['date']=df.index.astype('str').str[0:10]
df

pandas-task11-综合练习.md_第18张图片
这里数据应该是52万5千6百行,少一半的原因上面已经说了,是因为匹配的时候只匹配了H0-H11,之后的操作应该都没问题,所以就不改了。

2.正则表达式获取最高温和最低温

df3 = pd.read_csv('./data/qx1819.csv')
pat_temp='(.?\d+).{0,2}~\s{0,2}(.?\d+).?'
df3_temp=df3['气温'].str.extract(pat_temp).rename(columns={
     0:'最高温',1:'最低温'})
df3=pd.concat([df3,df3_temp],axis=1)
df3

pandas-task11-综合练习.md_第19张图片
这里可以使用isna()函数查看是否有没用匹配到的,可以用来检查正则规则是否合适,以及数据是否正常,这里我都花了些功夫修改正则表达式:

df3[df3['最高温'].isna()]

pandas-task11-综合练习.md_第20张图片
发现有两天数据只有一个值,我暂时把他丢弃。

df3=df3.dropna()
df3['温差']=df3['最高温'].astype('int')-df3['最低温'].astype('int')
df3

3.获取温差

pandas-task11-综合练习.md_第21张图片

df3.loc[df3['温差']<0]

在这里插入图片描述
有一天数据不符和左边下右边大的规则,可以修改下。

4.关系连接 merge

将处理好的df和含有温度信息的df3通过日期相连,这里两个日期的列名不同,需要手动指定。

注意保存df的index,如果不保存,连接后会形成新的index,原有的时间信息会丢失。

res1=df3[['日期','最高温','最低温','温差']]
df_index=df.index
df=df.merge(res1,left_on='date',right_on='日期',how='left').drop('date',1)
df.index=df_index
df

最终结果:
pandas-task11-综合练习.md_第22张图片

问题3:

当天是否有沙暴、是否有雾、是否有雨、是否有雪、是否为晴天

解决思路

1.contains

先看下有沙暴的

df3 = pd.read_csv('./data/qx1819.csv')
df3.loc[df3['天气'].str.contains('沙')]

pandas-task11-综合练习.md_第23张图片
设置新列记录雨雪雾

df3 = pd.read_csv('./data/qx1819.csv')
df3['沙暴']=df3['天气'].str.contains('沙').astype(int)
df3['有雾']=df3['天气'].str.contains('雾').astype(int)
df3['有雨']=df3['天气'].str.contains('雨').astype(int)
df3['有雪']=df3['天气'].str.contains('雪').astype(int)
df3

pandas-task11-综合练习.md_第24张图片

2.match+$

对于晴天不能用contains,因为这样会把阴转晴等也算在晴天
pandas-task11-综合练习.md_第25张图片
我妈可以使用match的方法,不过记得要匹配结尾,否则晴转多云等也会被匹配进去:

df3.loc[df3['天气'].str.match('晴$')]

pandas-task11-综合练习.md_第26张图片

注意这里endwith(‘晴’)也不行,会匹配多云转晴

pandas-task11-综合练习.md_第27张图片

df3['晴']=df3['天气'].str.match('晴$').astype(int)
df3

pandas-task11-综合练习.md_第28张图片

问题4:

选择一种合适的方法度量雨量/下雪量的大小(构造两个序列分别表示二者大小)

解决思路:

1.cat+contains获取所有含雨的天气类型

weather_type=df3['天气'].astype('category').cat.categories
rain_type=weather_type[rian_type.str.contains('雨')].tolist()
rain_type

一共42种,这里展示部分:
pandas-task11-综合练习.md_第29张图片

2.zip组成雨类型的字典

index1=[i for i in range(len(rain_type)) ]
rain_dict=dict(zip(rain_type, index1))
rain_dict

pandas-task11-综合练习.md_第30张图片

3.天气匹配下雨等级字典表

匹配不到的这里我用了异常捕获,填入变成缺失值

weather=df3['天气'].tolist()
rain=[]
for wea in weather:
    try:
        rain.append(rain_dict[wea])
    except:
        rain.append(np.NaN)
df3['下雨等级']=rain
df3

pandas-task11-综合练习.md_第31张图片
看下下雨等级非缺失值的那些:

df3.loc[df3['下雨等级'].notna()]

pandas-task11-综合练习.md_第32张图片

下雪等级情况完全一致,这里不再赘述

问题5:

限制只用4列,对风向进行0-1编码(只考虑风向,不考虑大小)

解决思路:

1.contains

这里题意也没完全弄懂,我按照自己的理解及出题人的回复就使用了最简单的做法,即当前风向中出现对应方向的风就将该列置为1,完成01编码,类似于one-hot向量,比如东北风转南风,出现了东、北、南,即东南西北四列分别为1101。
在这里插入图片描述

df3 = pd.read_csv('./data/qx1819.csv')
# pat_wind_dire='([东南西北]{1,2})风.([东南西北]{1,2})风|([东南西北]{1,2})风'
df3['东风']=df3['风向'].str.contains('东').astype(int)
df3['西风']=df3['风向'].str.contains('西').astype(int)
df3['南风']=df3['风向'].str.contains('南').astype(int)
df3['北风']=df3['风向'].str.contains('北').astype(int)
df3

pandas-task11-综合练习.md_第33张图片

其他思路:

群里小伙伴提供了另一种思路,不过由于时间原因无法继续实验:
在这里插入图片描述

就是先识别风向,然后对风向进行编码,最后对状态进行数据表示。 我的理解是,
识别风向:只有东西南北,以及东北、东南、西北、西南8种风向,先用extract提取 风向编码:可以用000-111编码
状态表示:感觉最后只需要两列,state1,state2,比如北风,应为000 NAN;东北风转北风 应为 101 000

剩余练习

对df的水压一列构造如下时序特征:

  • 当前时刻该站点水压与本月的相同整点时间该站点水压均值的差,例如当前时刻为2018-05-20 17:00:00,那么对应需要减去的值为当前月所有17:00:00时间点水压值的均值
    • 当前时刻所在周的周末该站点水压均值与工作日水压均值之差
    • 当前时刻向前7日内,该站点水压的均值、标准差、0.95分位数、下雨天数与下雪天数的总和
    • 当前时刻向前7日内,该站点同一整点时间水压的均值、标准差、0.95分位数
    • 当前时刻所在日的该站点水压最高值与最低值出现时刻的时间差

你可能感兴趣的:(pandas,python,数据分析,深度学习)