下面给出了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用相应模型名称填充,按照字母顺序排序,数值保留三位小数:
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)
A | B | |
---|---|---|
0 | Benchmarking Training float precision type mna... | mnasnet0_5 model average train time : 28.527... |
1 | Benchmarking 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)
name | type | time | |
---|---|---|---|
0 | mnasnet0_5 | Training_ float | 28.528 |
1 | mnasnet0_75 | Training_ float | 34.105 |
2 | mnasnet1_0 | Training_ float | 34.314 |
4. 长表变宽表
data = data.pivot(index='name',columns='type',values='time')
data = data.reset_index()
data.head()
type | name | Inference_ double | Inference_ float | Inference_ half | Training_ double | Training_ float | Training_ half |
---|---|---|---|---|---|---|---|
0 | densenet121 | 144.111 | 15.637 | 19.772 | 417.207 | 93.357 | 88.976 |
1 | densenet161 | 511.177 | 31.750 | 27.555 | 1290.287 | 136.624 | 144.319 |
2 | densenet169 | 175.808 | 21.598 | 26.371 | 511.404 | 104.840 | 121.556 |
3 | densenet201 | 223.960 | 26.169 | 33.394 | 654.365 | 129.334 | 118.940 |
4 | mnasnet0_5 | 11.870 | 8.039 | 6.929 | 48.232 | 28.528 | 27.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)
Time | MeasName | H0 | H1 | H2 | H3 | H4 | H5 | H6 | H7 | ... | H14 | H15 | H16 | H17 | H18 | H19 | H20 | H21 | H22 | H23 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
10948 | 2018-12-31 | 站点9 | 0.287250 | 0.301875 | 0.30600 | 0.30525 | 0.313500 | 0.301500 | 0.279750 | 0.253875 | ... | 0.241500 | 0.237750 | 0.233625 | 0.227625 | 0.209625 | 0.226500 | 0.21975 | 0.211500 | 0.241125 | 0.246375 |
10949 | 2018-12-31 | 站点6 | 0.313125 | 0.330375 | 0.33375 | 0.33450 | 0.337125 | 0.326625 | 0.310875 | 0.277875 | ... | 0.261375 | 0.259125 | 0.262125 | 0.252750 | 0.241500 | 0.252375 | 0.24675 | 0.239625 | 0.269250 | 0.269625 |
2 rows × 26 columns
df2.head(2)
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.4290 | 0.44025 | 0.445875 | 0.444750 | 0.417750 | 0.387000 | ... | 0.319875 | 0.32625 | 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.2575 | 0.24625 | 0.275125 | 0.264625 | 0.229375 | 0.205375 | ... | 0.180625 | 0.17650 | 0.181375 | 0.155125 | 0.159625 | 0.146125 | 0.144625 | 0.135250 | 0.158875 | 0.184750 |
2 rows × 26 columns
使用纵向拼接将df1和df2数据集合并,然后需要将H0-H23转换为对应的时间点,之后通过宽表变长表将日期和时间匹配
【START】
1. 拼接数据
df = pd.concat([df1,df2],axis=0,join='outer')
df.head(2)
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.426 | 0.42525 | 0.417375 | 0.426375 | ... | 0.348750 | 0.35925 | 0.35550 | 0.34425 | 0.352125 | 0.35625 | 0.34725 | 0.343875 | 0.356625 | 0.418875 |
1 | 2018-01-01 | 站点7 | 0.214375 | 0.226750 | 0.232375 | 0.233125 | 0.235 | 0.23275 | 0.230875 | 0.220000 | ... | 0.187375 | 0.19675 | 0.19975 | 0.19225 | 0.186250 | 0.18325 | 0.17725 | 0.163375 | 0.165250 | 0.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:00 | 01:00:00 | 02:00:00 | 03:00:00 | 04:00:00 | 05:00:00 | 06:00:00 | 07:00:00 | ... | 14:00:00 | 15:00:00 | 16:00:00 | 17:00:00 | 18:00:00 | 19:00:00 | 20:00:00 | 21:00:00 | 22:00:00 | 23:00:00 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 2018-01-01 | 站点4 | 0.402750 | 0.407625 | 0.418125 | 0.425250 | 0.426 | 0.42525 | 0.417375 | 0.426375 | ... | 0.348750 | 0.35925 | 0.35550 | 0.34425 | 0.352125 | 0.35625 | 0.34725 | 0.343875 | 0.356625 | 0.418875 |
1 | 2018-01-01 | 站点7 | 0.214375 | 0.226750 | 0.232375 | 0.233125 | 0.235 | 0.23275 | 0.230875 | 0.220000 | ... | 0.187375 | 0.19675 | 0.19975 | 0.19225 | 0.186250 | 0.18325 | 0.17725 | 0.163375 | 0.165250 | 0.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 | 站点2 | 0.332000 |
2019-12-31 23:00:00 | 站点9 | 0.201375 |
2019-12-31 23:00:00 | 站点6 | 0.000000 |
【END】
df3.head(3)
日期 | 天气 | 气温 | 风向 | |
---|---|---|---|---|
0 | 2018-01-01 | 多云 | 1C~-4C | 东南风 微风 |
1 | 2018-01-02 | 阴转多云 | 8C~0C | 东北风 3-4级 |
2 | 2018-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)
0 | 1 | 2 | |
---|---|---|---|
0 | 1 | -4 | 5 |
1 | 8 | 0 | 8 |
上面一步出现了问题:首先是会有存在空格的现象,采用替代的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 | 日期 | 最高气温 | 最低气温 | 温差 | |
---|---|---|---|---|---|---|---|---|
0 | 2018-01-01 | 站点4 | 0.402750 | 2018-01-01 | 2018-01-01 | 1.0 | -4.0 | 5.0 |
1 | 2018-01-01 | 站点7 | 0.214375 | 2018-01-01 | 2018-01-01 | 1.0 | -4.0 | 5.0 |
【END】
我们想要返回布尔类型,因此可以直接使用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)
日期 | 天气 | 气温 | 风向 | 是否沙暴 | 是否有雾 | 是否有雨 | 是否有雪 | 是否晴天 | |
---|---|---|---|---|---|---|---|---|---|
727 | 2019-12-30 | 阴转晴 | 4℃~-6℃ | 东北风转北风 4-5级转4-5级 | False | False | False | False | True |
728 | 2019-12-31 | 晴转多云 | 0℃~-5℃ | 西风转南风 <3级 | False | False | False | False | True |
#将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 | 天气 | 气温 | 风向 | 最高气温 | 最低气温 | 温差 | 是否沙暴 | 是否有雾 | 是否有雨 | 是否有雪 | 是否晴天 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
525598 | 2019-12-31 23:00:00 | 站点9 | 0.201375 | 2019-12-31 | 晴转多云 | 0℃~-5℃ | 西风转南风 <3级 | 0.0 | -5.0 | 5.0 | False | False | False | False | True |
525599 | 2019-12-31 23:00:00 | 站点6 | 0.000000 | 2019-12-31 | 晴转多云 | 0℃~-5℃ | 西风转南风 <3级 | 0.0 | -5.0 | 5.0 | False | False | False | False | True |
【END】
雨量使用水压站点当天的最大压力来度量,下雪量的大小通过天气中的雪的类型来区分,设置为分类数据类型
【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 | 天气 | 气温 | 风向 | 最高气温 | 最低气温 | 温差 | 是否沙暴 | 是否有雾 | 是否有雨 | 是否有雪 | 是否晴天 | 雨量大小 | 雪量大小 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
450 | 2018-01-16 | 站点4 | 0.396375 | 2018-01-16 | 雨夹雪转阴 | 4C~-1C | 东北风转南风 3-4级转3-4级 | 4.0 | -1.0 | 5.0 | False | False | True | True | False | 小 | 夹雪 |
451 | 2018-01-16 | 站点7 | 0.209500 | 2018-01-16 | 雨夹雪转阴 | 4C~-1C | 东北风转南风 3-4级转3-4级 | 4.0 | -1.0 | 5.0 | False | False | True | True | False | 小 | 夹雪 |
【END】
首先查看一下风向的种类,发现有很多类别,这里选取后两位作为它的主要风向(这里我认为并不是最优的)
【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 | 天气 | 气温 | 风向 | 最高气温 | 最低气温 | 温差 | ... | 是否有雾 | 是否有雨 | 是否有雪 | 是否晴天 | 雨量大小 | 雪量大小 | 东风 | 西风 | 南风 | 北风 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
525598 | 2019-12-31 23:00:00 | 站点9 | 0.201375 | 2019-12-31 | 晴转多云 | 0℃~-5℃ | 西风转南风 <3级 | 0.0 | -5.0 | 5.0 | ... | False | False | False | True | NaN | NaN | 0 | 0 | 1 | 0 |
525599 | 2019-12-31 23:00:00 | 站点6 | 0.000000 | 2019-12-31 | 晴转多云 | 0℃~-5℃ | 西风转南风 <3级 | 0.0 | -5.0 | 5.0 | ... | False | False | False | True | NaN | NaN | 0 | 0 | 1 | 0 |
2 rows × 21 columns
【END】
首先计算按月到时刻、站点的均值,然后拼接到主表,最后进行计算
【START】
#对df进行改造,新增月和时刻的列值
df = pd.DataFrame(df_h[['Time','date','站点','压力','是否有雨','是否有雪']])
df['month'] = df['Time'].dt.month
df['hour'] = df['Time'].dt.hour
df.head()
Time | date | 站点 | 压力 | 是否有雨 | 是否有雪 | month | hour | |
---|---|---|---|---|---|---|---|---|
0 | 2018-01-01 | 2018-01-01 | 站点4 | 0.402750 | False | False | 1 | 0 |
1 | 2018-01-01 | 2018-01-01 | 站点7 | 0.214375 | False | False | 1 | 0 |
2 | 2018-01-01 | 2018-01-01 | 站点22 | 0.247000 | False | False | 1 | 0 |
3 | 2018-01-01 | 2018-01-01 | 站点21 | 0.284250 | False | False | 1 | 0 |
4 | 2018-01-01 | 2018-01-01 | 站点20 | 0.292875 | False | False | 1 | 0 |
#到月到时段的均值计算
df_month = df.groupby(['month','hour','站点'])['压力'].mean()
df_month = df_month.reset_index()
df_month.head()
month | hour | 站点 | 压力 | |
---|---|---|---|---|
0 | 1 | 0 | 站点1 | 0.260095 |
1 | 1 | 0 | 站点10 | 0.259512 |
2 | 1 | 0 | 站点11 | 0.244476 |
3 | 1 | 0 | 站点12 | 0.252960 |
4 | 1 | 0 | 站点13 | 0.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)
Time | date | 站点 | 压力 | 是否有雨 | 是否有雪 | month | hour | 平均压力 | |
---|---|---|---|---|---|---|---|---|---|
21909 | 2018-01-01 01:00:00 | 2018-01-01 | 站点1 | 0.292000 | False | False | 1 | 1 | 0.266966 |
21939 | 2018-01-02 01:00:00 | 2018-01-02 | 站点1 | 0.291625 | False | False | 1 | 1 | 0.266966 |
21969 | 2018-01-03 01:00:00 | 2018-01-03 | 站点1 | 0.296500 | False | True | 1 | 1 | 0.266966 |
【END】
首先找到站点的周末和工作日,然受计算周末和工作日的均值,最后再按照站点、年、月、周进行汇总
【START】
#增加年、周、工作日维度
df['year'] = df['Time'].dt.year
df['week'] = df['Time'].dt.isocalendar().week
df['day_week'] = df['Time'].dt.dayofweek
df.head(2)
Time | date | 站点 | 压力 | 是否有雨 | 是否有雪 | month | hour | 平均压力 | year | week | day_week | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
9 | 2018-01-01 | 2018-01-01 | 站点1 | 0.288625 | False | False | 1 | 0 | 0.260095 | 2018 | 1 | 0 |
39 | 2018-01-02 | 2018-01-02 | 站点1 | 0.286750 | False | False | 1 | 0 | 0.260095 | 2018 | 1 | 1 |
#周末的水压均值
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)
站点 | year | month | week | 周末平均压力 | |
---|---|---|---|---|---|
0 | 站点1 | 2018 | 1 | 1 | 0.251711 |
1 | 站点1 | 2018 | 1 | 2 | 0.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)
站点 | year | month | week | 工作日平均压力 | |
---|---|---|---|---|---|
0 | 站点1 | 2018 | 1 | 1 | 0.253222 |
1 | 站点1 | 2018 | 1 | 2 | 0.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)
Time | date | 站点 | 压力 | 是否有雨 | 是否有雪 | month | hour | 平均压力 | year | week | day_week | 周末平均压力 | 工作日平均压力 | 周末与工作日压力差值 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
525598 | 2019-12-30 23:00:00 | 2019-12-30 | 站点9 | 0.225375 | False | False | 12 | 23 | 0.247349 | 2019 | 1 | 0 | NaN | 0.218828 | NaN |
525599 | 2019-12-31 23:00:00 | 2019-12-31 | 站点9 | 0.201375 | False | False | 12 | 23 | 0.247349 | 2019 | 1 | 1 | NaN | 0.218828 | NaN |
【END】
我理解这一问求得是到日的结果,不到时刻对应的结果,按照每个不同的站点,使用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-01 | NaN | 站点2 |
2018-01-02 | NaN | 站点2 |
2018-01-03 | NaN | 站点2 |
2018-01-04 | NaN | 站点2 |
2018-01-05 | NaN | 站点2 |
... | ... | ... |
2019-12-27 | 0.335159 | 站点2 |
2019-12-28 | 0.335098 | 站点2 |
2019-12-29 | 0.334743 | 站点2 |
2019-12-30 | 0.335152 | 站点2 |
2019-12-31 | 0.335009 | 站点2 |
2920 rows × 2 columns
【END】
依照上面的方法,我们多加一个时刻的参数即可
【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:00 | NaN | 站点2 |
2018-01-02 00:00:00 | NaN | 站点2 |
2018-01-03 00:00:00 | NaN | 站点2 |
2018-01-04 00:00:00 | NaN | 站点2 |
2018-01-05 00:00:00 | NaN | 站点2 |
... | ... | ... |
2019-12-27 23:00:00 | 0.338964 | 站点2 |
2019-12-28 23:00:00 | 0.339286 | 站点2 |
2019-12-29 23:00:00 | 0.339982 | 站点2 |
2019-12-30 23:00:00 | 0.341054 | 站点2 |
2019-12-31 23:00:00 | 0.339714 | 站点2 |
20440 rows × 2 columns
先求出当前日的水压最高点和最低点时刻,然后再算时间差
【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 | |
---|---|---|---|
0 | 2018-01-01 | 站点1 | -1 days +18:00:00 |
1 | 2018-01-02 | 站点1 | -1 days +18:00:00 |
【END】
在题目2中遇到的最大的问题是,当写了很多条赋值语句的时候,命名如果不具有代表性,很难清晰的知道之前的含义,在之后的学习中一定要规避这个问题,尽量将名称认真的取名。
整个做题的过程中,大部分的思维方式都是基于表格运算的思维方式,这个方式可以解决问题,但是可能并不是最优的方案,之后还需要更多的去了解python内的知识,转变自己的思维方式。
最后,要养成写备注的习惯!!!