Task 11 综合练习
小结
- 题目链接: http://datawhale.club/t/topic/579/6
- 其他
- 转换命令 jupyter nbconvert --to markdown E:\PycharmProjects\TianChiProject\00_山枫叶纷飞\competitions\008_joyful-pandas\pandas_end_test.ipynb
【任务四】显卡日志
下面给出了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用相应模型名称填充,按照字母顺序排序,数值保留三位小数:
Train_half Train_float Train_double Inference_half Inference_float Inference_double
model_1 0.954 0.901 0.357 0.281 0.978 1.130
model_2 0.360 0.794 0.011 1.083 1.137 0.394
… … … … … … …
【数据下载】链接:https://pan.baidu.com/s/1CjfdtavEywHtZeWSmCGv3A 4 提取码:4mui
任务四思路
任务四题解代码
import numpy as np
import pandas as pd
benchmark_str = ''
benchmark_file_name = 'E:\\阿里云开发者-天池比赛\\08_pandas基础学习\\benchmark.txt'
with open(benchmark_file_name, 'r') as f:
benchmark_str += f.read()
# 取出开头和结尾 [Benchmarking Training, benchmark end :]
str_arrs = benchmark_str.split('Benchmarking ')
str_arrs = str_arrs[1:]
str_arrs[-1] = str_arrs[-1].split('benchmark end')[0]
str_arrs = [x.strip() for x in str_arrs]
str_arrs[:3]
['Training float precision type mnasnet0_5\nmnasnet0_5 model average train time : 28.527636528015137 ms',
'Training float precision type mnasnet0_75\nmnasnet0_75 model average train time : 34.10548686981201 ms',
'Training float precision type mnasnet1_0\nmnasnet1_0 model average train time : 34.31377410888672 ms']
"""
['Training float precision type mnasnet0_5\nmnasnet0_5 model average train time : 28.527636528015137 ms',
'Training float precision type mnasnet0_75\nmnasnet0_75 model average train time : 34.10548686981201 ms',
'Training float precision type mnasnet1_0\nmnasnet1_0 model average train time : 34.31377410888672 ms']
"""
# 构建一个model_name对上所有的train和inference的字典
data_map = {}
def construct_data(model_name, status, value_name, value):
if data_map.get(model_name) is None:
data_map[model_name]=[np.nan for x in range(0, 6)]
idx=0
idx_offset=0
if status != 'Training':
idx_offset=3
if value_name == 'half': idx=0
elif value_name == 'float': idx=1
elif value_name == 'double': idx=2
else:
raise RuntimeError('Error ' + value_name)
_idx = idx + idx_offset
# print( data_map[model_name], _idx , '==', idx , idx_offset)
data_map[model_name][_idx] = format(float(value), '.3f')
# print( data_map[model_name])
for x in str_arrs:
strs = list(filter(lambda item : item != ' ' or item != '', x.split(' ')))
# ['Training', 'float', 'precision',
# 'type', 'mnasnet0_5\nmnasnet0_5', '',
# 'model', 'average', 'train',
# 'time', ':', '', '28.527636528015137', 'ms']
construct_data(strs[4].split('\n')[0], strs[0], strs[1], strs[-2])
print('map转为df')
piece_dfs = []
for key in data_map.keys():
vals = data_map[key]
piece_df = pd.DataFrame({
'model_name': [key],
'Train_half':[vals[0]],
'Train_float':[vals[1]],
'Train_double':[vals[2]],
'Inference_half':[vals[3]],
'Inference_float':[vals[4]],
'Inference_double':[vals[5]]
})
piece_dfs.append(piece_df)
res = pd.concat(piece_dfs)
map转为df
res.set_index('model_name', inplace=True)
res.head()
|
Train_half |
Train_float |
Train_double |
Inference_half |
Inference_float |
Inference_double |
model_name |
|
|
|
|
|
|
mnasnet0_5 |
27.198 |
28.528 |
48.232 |
6.929 |
8.039 |
11.870 |
mnasnet0_75 |
28.787 |
34.105 |
70.395 |
6.010 |
6.246 |
18.154 |
mnasnet1_0 |
29.600 |
34.314 |
88.913 |
6.785 |
6.553 |
25.796 |
mnasnet1_3 |
35.175 |
35.557 |
118.835 |
6.457 |
6.871 |
35.082 |
resnet18 |
16.520 |
18.660 |
241.416 |
4.399 |
5.595 |
83.730 |
【任务五】水压站点的特征工程
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')
通过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
在上一问构造的df基础上,构造下面的特征序列或DataFrame,并把它们逐个拼接到df的右侧
当天最高温、最低温和它们的温差
当天是否有沙暴、是否有雾、是否有雨、是否有雪、是否为晴天
选择一种合适的方法度量雨量/下雪量的大小(构造两个序列分别表示二者大小)
限制只用4列,对风向进行0-1编码
【数据下载】链接:https://pan.baidu.com/s/1Tqad4b7zN1HBbc-4t4xc6w 1 提取码:ijbd
任务五思路
任务五题解代码
import numpy as np
import pandas as pd
file_prefix = 'E:\\阿里云开发者-天池比赛\\08_pandas基础学习\\水压站点\\'
df1 = pd.read_csv(file_prefix + 'yali18.csv')
df2 = pd.read_csv(file_prefix + 'yali19.csv')
df3 = pd.read_csv(file_prefix + '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
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级 |
5.1 通过df1和df2构造df
通过df1和df2构造df,把时间设为索引,第一列为站点编号,第二列为对应时刻的压力大小,排列方式如下(压力数值请用正确的值替换):
站点 压力
2018-01-01 00:00:00 1 1.0
2018-01-01 00:00:00 2 1.0
concat_df = pd.concat([df1, df2])
def construct_piece_df(st_time, station_name, datas=[]):
# print(st_time, station_name, datas)
assert len(datas)==24
st = pd.to_datetime(st_time)
peice_df = pd.DataFrame(
index=pd.date_range(start=pd.to_datetime(st), periods=24, freq='1H'))
peice_df['站点'] = station_name
peice_df['压力'] = datas
return peice_df
piece_dfs = []
hour_list = ['H' + str(i) for i in range(0, 24)]
for row_num in range(concat_df.shape[0]):
row = concat_df.iloc[row_num]
df = construct_piece_df(row['Time'], row['MeasName'], [row[hour] for hour in hour_list ])
# print(df)
piece_dfs.append(df)
df = pd.concat(piece_dfs)
df.head()
|
站点 |
压力 |
2018-01-01 00:00:00 |
站点4 |
0.402750 |
2018-01-01 01:00:00 |
站点4 |
0.407625 |
2018-01-01 02:00:00 |
站点4 |
0.418125 |
2018-01-01 03:00:00 |
站点4 |
0.425250 |
2018-01-01 04:00:00 |
站点4 |
0.426000 |
print(df.shape)
(525600, 2)
5.2 构造下面的特征序列
print('当天最高温、最低温和它们的温差')
df3.head(2)
当天最高温、最低温和它们的温差
|
日期 |
天气 |
气温 |
风向 |
0 |
2018-01-01 |
多云 |
1C~-4C |
东南风 微风 |
1 |
2018-01-02 |
阴转多云 |
8C~0C |
东北风 3-4级 |
print('此处温度有坑,需要处理为统一值')
print(df3.loc[0])
df3.iloc[469]
此处温度有坑,需要处理为统一值
日期 2018-01-01
天气 多云
气温 1C~-4C
风向 东南风 微风
Name: 0, dtype: object
日期 2019-04-16
天气 雷阵雨转多云
气温 19℃~10℃
风向 南风 <3级
Name: 469, dtype: object
print('统一将℃转为C, 统一格式')
df3['气温'] = df3['气温'].apply(lambda x:str(x).replace('℃ ', 'C').replace('℃', 'C').replace('C ', 'C'))
df3.iloc[469]
统一将℃转为C
日期 2019-04-16
天气 雷阵雨转多云
气温 19C~10C
风向 南风 <3级
最高温 19
最低温 10
Name: 469, dtype: object
df3['最高温'] = df3['气温'].apply(lambda x : x.split('~')[0][:-1])
df3['最低温'] = df3['气温'].apply(lambda x : x.split('~')[1][:-1])
df3['最高温'] = df3['最高温'].replace('', np.nan)
df3['最低温'] = df3['最低温'].replace('', np.nan)
df3['最高温'] = pd.to_numeric(df3['最高温'], errors='ignore')
df3['最低温'] = pd.to_numeric(df3['最低温'], errors='ignore')
print(df3['最高温'].head())
print(df3['最低温'].head())
0 1.0
1 8.0
2 1.0
3 0.0
4 3.0
Name: 最高温, dtype: float64
0 -4
1 0
2 -1
3 -4
4 -4
Name: 最低温, dtype: int64
df3['温差'] = df3['最高温'] - df3['最低温']
df3.head(3)
|
日期 |
天气 |
气温 |
风向 |
最高温 |
最低温 |
温差 |
0 |
2018-01-01 |
多云 |
1C~-4C |
东南风 微风 |
1.0 |
-4 |
5.0 |
1 |
2018-01-02 |
阴转多云 |
8C~0C |
东北风 3-4级 |
8.0 |
0 |
8.0 |
2 |
2018-01-03 |
阴转小雪 |
1C~-1C |
东北风 4-5级转4-5级 |
1.0 |
-1 |
2.0 |
wea_list = ['沙暴', '雾','雨','雪','晴' ]
for wea in wea_list:
df3[wea] = df3['天气'].apply(lambda x : x is not None and len(str(x))>0 and str(x).count(wea)>0)
df3.head()
|
日期 |
天气 |
气温 |
风向 |
最高温 |
最低温 |
温差 |
沙暴 |
雾 |
雨 |
雪 |
晴 |
0 |
2018-01-01 |
多云 |
1C~-4C |
东南风 微风 |
1.0 |
-4 |
5.0 |
False |
False |
False |
False |
False |
1 |
2018-01-02 |
阴转多云 |
8C~0C |
东北风 3-4级 |
8.0 |
0 |
8.0 |
False |
False |
False |
False |
False |
2 |
2018-01-03 |
阴转小雪 |
1C~-1C |
东北风 4-5级转4-5级 |
1.0 |
-1 |
2.0 |
False |
False |
False |
True |
False |
3 |
2018-01-04 |
阴 |
0C~-4C |
东北风转北风 3-4级转3-4级 |
0.0 |
-4 |
4.0 |
False |
False |
False |
False |
False |
4 |
2018-01-05 |
阴转多云 |
3C~-4C |
西风转北风 3-4级转3-4级 |
3.0 |
-4 |
7.0 |
False |
False |
False |
False |
False |
print('度量雨量的所有集合:')
set(list(filter(lambda x : x is not None and str(x).count('雨')>0, df3['天气']))).__str__()
度量雨量的所有集合:
"{'多云转阵雨', '多云转小到中雨', '多云转小雨', '中雨转小雨', '多云转中雨', '晴转小雨', '阴转雷阵雨', '小雨', '雾转雨夹雪', '雷阵雨转阴', '阴转大雨', '雨夹雪转阴', '大雨转小雨', '雨夹雪转大雪', '小雨转阵雨', '小雨转阴', '阴转中雨', '多云转中到大雨', '扬沙转雨夹雪', '小雨转中雨', '雨夹雪转多云', '小雨转多云', '中雨转多云', '暴雨', '大雨转多云', '中雨转暴雨', '阴转小雨', '阴转小到中雨', '雨转阴', '雾转小雨', '中雨转阴', '雷阵雨', '阴转雨夹雪', '阴转阵雨', '中雨转雷阵雨', '晴转阵雨', '中雨转小到中雨', '雨转多云', '雷阵雨转多云', '阴转中到大雨', '小雨转雷阵雨', '暴雨转雷阵雨', '多云转雷阵雨'}"
print('度量下雪量的所有集合:')
set(list(filter(lambda x : x is not None and str(x).count('雪')>0, df3['天气']))).__str__()
度量下雪量的所有集合:
"{'多云转小到中雪', '雨夹雪转阴', '扬沙转雨夹雪', '阴转雨夹雪', '阴转中到大雪', '雨夹雪转多云', '大雪转多云', '多云转小雪', '小雪转晴', '雨夹雪转大雪', '阴转小雪', '雾转雨夹雪'}"
rain_level = ['雨', '小雨', '中雨', '大雨', '阵雨', '雷阵雨','暴雨']
snow_level = ['雪', '小雪', '中雪', '大雪', '暴雪']
def get_level(item, arrs):
x = '' if item is None else str(item)
for idx in range(len(arrs)-1,-1, -1):
if x.count(arrs[idx]):
return idx
return 0
df3['rain_level'] = df3['天气'].apply(lambda x : get_level(x, rain_level))
df3['snow_level'] = df3['天气'].apply(lambda x : get_level(x, snow_level))
df3['rain_level']. head()
0 0
1 0
2 0
3 0
4 0
Name: rain_level, dtype: int64
print('度量 风 的所有集合:')
set(list(filter(lambda x : x is not None and str(x).count('风')>0, df3['风向']))).__str__()
度量 风 的所有集合:
"{'北风 微风', '转西风 转', '东风转北风 <3级转<3级', '东风转东南风 3-4级', '东北风转东南风 3-4级转3-4级', '西风转东南风 3-4级转3-4级', '西风转西南风 3-4级转3-4级', '北风转东北风 3-4级', '西风转北风 4-5级转4-5级', '东南风转北风 3-4级转3-4级', '东北风 3-4级', '西风转北风 4-5级', '西风转西北风 3-4级转3-4级', '东南风转东北风 <3级', '西南风转西风 3-4级转3-4级', '东南风转南风 4-5级转4-5级', '东北风转北风 5-6级转5-6级', '南风转北风 <3级', '东南风 3-4级转3-4级', '东南风转东风 3-4级转3-4级', '南风 4-5级', '西北风转南风 3-4级', '东南风转南风 <3级', '西风转北风 <3级', '东北风转南风 3-4级转3-4级', '北风 3-4级', '东北风转北风 4-5级转4-5级', '东北风 4-5级', '西南风转南风 5-6级转5-6级', '西北风 4-5级转4-5级', '东南风转东风 <3级', '西北风转西风 4-5级转4-5级', '西北风转东北风 3-4级', '东南风转南风 3-4级转3-4级', '西南风转东风 <3级', '西南风转北风 3-4级', '南风 3-4级', '东北风转东风 <3级转<3级', '东南风转西南风 <3级转<3级', '东北风 <3级', '西南风转南风 <3级', '东风转东北风 3-4级转3-4级', '东风转南风 3-4级转3-4级', '西风转南风 <3级', '西风 3-4级转3-4级', '东南风 <3级', '北风转东风 <3级', '西南风转北风 <3级转<3级', '南风转东南风 3-4级转3-4级', '西北风转西南风 3-4级转3-4级', '北风转微风 3-4级转3-4级', '东北风 4-5级转4-5级', '东风 3-4级', '北风转西风 4-5级转4-5级', '西南风转南风 4-5级转4-5级', '西风转东北风 4-5级转4-5级', '东南风转东风 4-5级', '西南风 3-4级转3-4级', '西北风转北风 <3级', '东南风 微风', '东北风转东风 <3级', '东北风转北风 <3级', '东南风转南风 4-5级', '东北风转东风 4-5级转4-5级', '东风转东北风 4-5级转4-5级', '西风转南风 3-4级转3-4级', '北风转东风 3-4级', '西风转西南风 4-5级转4-5级', '南风 3-4级转3-4级', '西南风转东南风 3-4级', '西风转西北风 5-6级转5-6级', '西风转东风 3-4级', '北风转南风 3-4级转3-4级', '南风转北风 3-4级转3-4级', '西南风转南风 3-4级转3-4级', '东北风转东南风 3-4级', '东风转北风 <3级', '北风转南风 <3级', '西南风 4-5级转4-5级', '西北风转南风 4-5级', '东风转南风 <3级转<3级', '东北风转北风 3-4级转3-4级', '西南风转南风 3-4级', '东风转南风 5-6级转5-6级', '西北风 4-5级', '南风 <3级', '南风转东南风 3-4级', '西南风转北风 3-4级转3-4级', '南风转北风 4-5级转4-5级', '东风 4-5级转4-5级', '西南风转东风 3-4级转3-4级', '西北风转东南风 3-4级转3-4级', '东风转东南风 3-4级转3-4级', '北风转西北风 3-4级', '东风 <3级', '东北风转西风 3-4级转3-4级', '东北风转南风 4-5级转4-5级', '南风 4-5级转4-5级', '东南风转北风 <3级', '东北风转南风 <3级', '南风转东风 3-4级转3-4级', '北风 4-5级', '西北风转西风 3-4级转3-4级', '西风转东风 3-4级转3-4级', '西风转东北风 3-4级', '北风 3-4级转3-4级', '东风转西风 3-4级', '南风转东南风 <3级转<3级', '北风转东北风 <3级转<3级', '北风转西北风 3-4级转3-4级', '东风转北风 3-4级', '北风 <3级', '西风转西南风 3-4级', '东北风转西北风 3-4级', '南风转东北风 3-4级转3-4级', '南风转东北风 <3级', '西南风转北风 4-5级转4-5级', '西南风转北风 <3级', '东风转东北风 <3级', '西风转北风 3-4级', '东风 4-5级', '西风转东风 <3级转<3级', '西南风 3-4级', '西北风转北风 4-5级转4-5级', '东南风转东北风 <3级转<3级', '东南风转东北风 3-4级', '北风转南风 3-4级', '西风转西南风 4-5级', '东北风转北风 4-5级', '南风转东风 <3级转<3级', '东南风转北风 3-4级', '东北风转西北风 3-4级转3-4级', '西北风转南风 3-4级转3-4级', '南风转东北风 3-4级', '西北风转南风 4-5级转4-5级', '东风转南风 3-4级', '南风 <3级转<3级', '西风 <3级', '西南风转南风 6-7级转6-7级', '北风转东北风 4-5级转4-5级', '北风转东南风 4-5级转4-5级', '西风转西北风 4-5级转4-5级', '西北风 微风', '东北风转南风 3-4级', '东北风转北风 3-4级', '西北风转北风 3-4级转3-4级', '东南风转东风 <3级转<3级', '西风转北风 3-4级转3-4级', '西南风转东北风 3-4级转3-4级', '东风转北风 3-4级转3-4级', '西南风转东北风 3-4级', '东风转东北风 3-4级', '南风转东南风 <3级', '东南风转东北风 3-4级转3-4级', '东北风 3-4级转3-4级', '西风 4-5级转4-5级', '北风转东南风 3-4级转3-4级', '南风转西风 3-4级', '东风 3-4级转3-4级', '北风转西风 <3级', '西北风转西风 5-6级转5-6级', '转东北风 转', '西风转东北风 3-4级转3-4级', '东南风转东风 3-4级', '北风 4-5级转4-5级', '东北风 5-6级转5-6级', '东北风转东风 3-4级转3-4级', '东南风转南风 3-4级', '东北风转南风 5-6级转5-6级', '西北风 3-4级转3-4级', '东北风转西南风 3-4级转3-4级', '南风 微风', '西风转南风 3-4级', '北风转东北风 3-4级转3-4级', '南风转北风 3-4级', '西风 3-4级', '西北风转北风 3-4级', '北风转东风 3-4级转3-4级', '东北风转东风 3-4级', '东南风 3-4级', '东风转东南风 <3级', '南风转西南风 3-4级', '西南风转南风 4-5级'}"
df3.head(1)
|
日期 |
天气 |
气温 |
风向 |
最高温 |
最低温 |
温差 |
沙暴 |
雾 |
雨 |
雪 |
晴 |
rain_level |
snow_level |
0 |
2018-01-01 |
多云 |
1C~-4C |
东南风 微风 |
1.0 |
-4 |
5.0 |
False |
False |
False |
False |
False |
0 |
0 |
print('限制只用4列,对风向进行0-1编码'
'\n直接东南西北各一列即可')
wind_dirs = ['东','南','西','北']
for wind_dir in wind_dirs:
df3[wind_dir + '风'] = df3['风向'].apply(lambda x : 1 if x is not None and str(x).count(wind_dir)>0 else 0)
df3.head(2)
限制只用4列,对风向进行0-1编码
直接东南西北各一列即可
|
日期 |
天气 |
气温 |
风向 |
最高温 |
最低温 |
温差 |
沙暴 |
雾 |
雨 |
雪 |
晴 |
rain_level |
snow_level |
东风 |
南风 |
西风 |
北风 |
0 |
2018-01-01 |
多云 |
1C~-4C |
东南风 微风 |
1.0 |
-4 |
5.0 |
False |
False |
False |
False |
False |
0 |
0 |
1 |
1 |
0 |
0 |
1 |
2018-01-02 |
阴转多云 |
8C~0C |
东北风 3-4级 |
8.0 |
0 |
8.0 |
False |
False |
False |
False |
False |
0 |
0 |
1 |
0 |
0 |
1 |
df.tail(1)
|
站点 |
压力 |
2019-12-31 23:00:00 |
站点6 |
0.0 |
print('把它们(df3)逐个拼接到df的右侧')
new_add_list = ['最高温', '最低温', '温差'] + ['rain_level'] + ['snow_level'] +wind_dirs
df['Date'] = df.index.to_series().apply(lambda x:x.strftime('%Y-%m-%d'))
df['DateTime'] = df.index.to_series()
df.tail(2)
把它们(df3)逐个拼接到df的右侧
|
站点 |
压力 |
Date |
DateTime |
2019-12-31 22:00:00 |
站点6 |
0.0 |
2019-12-31 |
2019-12-31 22:00:00 |
2019-12-31 23:00:00 |
站点6 |
0.0 |
2019-12-31 |
2019-12-31 23:00:00 |
df_merge = df.merge(df3, left_on='Date', right_on='日期', how='left')
df_merge.drop(axis=1, columns=['Date', '日期'], inplace=True)
df_merge.head(1)
|
站点 |
压力 |
DateTime |
天气 |
气温 |
风向 |
最高温 |
最低温 |
温差 |
沙暴 |
雾 |
雨 |
雪 |
晴 |
rain_level |
snow_level |
东风 |
南风 |
西风 |
北风 |
0 |
站点4 |
0.40275 |
2018-01-01 |
多云 |
1C~-4C |
东南风 微风 |
1.0 |
-4.0 |
5.0 |
False |
False |
False |
False |
False |
0.0 |
0.0 |
1.0 |
1.0 |
0.0 |
0.0 |
对df的水压一列构造如下时序特征:
- 当前时刻该站点水压与本月的相同整点时间水压均值的差,例如当前时刻为2018-05-20 17:00:00,那么对应需要减去的值为当前月所有17:00:00时间点水压值的均值
print('判断df的dateTime是否正常~')
df_merge.tail(1)
判断df的dateTime是否正常~
|
站点 |
压力 |
DateTime |
天气 |
气温 |
风向 |
最高温 |
最低温 |
温差 |
沙暴 |
雾 |
雨 |
雪 |
晴 |
rain_level |
snow_level |
东风 |
南风 |
西风 |
北风 |
525599 |
站点6 |
0.0 |
2019-12-31 23:00:00 |
晴转多云 |
0C~-5C |
西风转南风 <3级 |
0.0 |
-5.0 |
5.0 |
False |
False |
False |
False |
True |
0.0 |
0.0 |
0.0 |
1.0 |
1.0 |
0.0 |
0 0.123496
1 137.101624
2 0.122745
3 0.128189
4 0.132111
...
525595 -0.228792
525596 -0.227006
525597 -0.215604
525598 -0.219826
525599 -0.253118
Name: 压力, Length: 525600, dtype: float64
- 当前时刻所在周的周末该站点水压均值与工作日水压均值之差
先过滤出周末或者工作日, 再按周进行分组, 做差
- 注意有两年的数据,week分组需要带上年份
x = df_merge.DateTime.dt.year.to_frame()
x
# +'_'+ df_merge.DateTime.dt.week.to_frame().apply(lambda x:str(x))
|
DateTime |
0 |
2018 |
1 |
2018 |
2 |
2018 |
3 |
2018 |
4 |
2018 |
... |
... |
525595 |
2019 |
525596 |
2019 |
525597 |
2019 |
525598 |
2019 |
525599 |
2019 |
525600 rows × 1 columns
df_merge['year_week'] = df_merge.DateTime.dt.year.to_frame().astype(str)+'_'+ df_merge.DateTime.dt.week.to_frame().astype(str)
df_merge['year_week']
D:\Anaconda3\lib\site-packages\ipykernel_launcher.py:1: FutureWarning: Series.dt.weekofyear and Series.dt.week have been deprecated. Please use Series.dt.isocalendar().week instead.
"""Entry point for launching an IPython kernel.
0 2018_1
1 2018_1
2 2018_1
3 2018_1
4 2018_1
...
525595 2019_1
525596 2019_1
525597 2019_1
525598 2019_1
525599 2019_1
Name: year_week, Length: 525600, dtype: object
week_delta = \
df_merge[np.where(df_merge.DateTime.dt.weekday>=5, True, False)].groupby(['year_week'])['压力'].mean().to_frame() \
- \
df_merge[np.where(df_merge.DateTime.dt.weekday>=5, False, True)].groupby(['year_week'])['压力'].mean().to_frame()
week_delta.reset_index(inplace=True)
week_delta
|
year_week |
压力 |
0 |
2018_1 |
-0.006236 |
1 |
2018_10 |
-0.003222 |
2 |
2018_11 |
-0.001048 |
3 |
2018_12 |
-0.002119 |
4 |
2018_13 |
-0.002721 |
... |
... |
... |
99 |
2019_52 |
-0.006232 |
100 |
2019_6 |
-0.009789 |
101 |
2019_7 |
0.002529 |
102 |
2019_8 |
-0.003469 |
103 |
2019_9 |
-0.001488 |
104 rows × 2 columns
df_merge_week_delta = df_merge.merge(week_delta, left_on='year_week', right_on='year_week', how='left')
df_merge_week_delta.tail(2)
|
站点 |
压力_x |
DateTime |
天气 |
气温 |
风向 |
最高温 |
最低温 |
温差 |
沙暴 |
... |
雪 |
晴 |
rain_level |
snow_level |
东风 |
南风 |
西风 |
北风 |
year_week |
压力_y |
525598 |
站点6 |
0.0 |
2019-12-31 22:00:00 |
晴转多云 |
0C~-5C |
西风转南风 <3级 |
0.0 |
-5.0 |
5.0 |
False |
... |
False |
True |
0.0 |
0.0 |
0.0 |
1.0 |
1.0 |
0.0 |
2019_1 |
-0.013671 |
525599 |
站点6 |
0.0 |
2019-12-31 23:00:00 |
晴转多云 |
0C~-5C |
西风转南风 <3级 |
0.0 |
-5.0 |
5.0 |
False |
... |
False |
True |
0.0 |
0.0 |
0.0 |
1.0 |
1.0 |
0.0 |
2019_1 |
-0.013671 |
2 rows × 22 columns
- 当前时刻向前7日内,该站点水压的均值、标准差、0.95分位数、下雨天数与下雪天数的总和
简单思路
- 分组: 站点 日期 水压值
- 错误的写法:df_merge.rolling('7D').transform(['mean', 'std', mask_fun_quantile, sum_rain_snow_days])
- 尝试 先分组,再在apply中进行单独处理
df_merge.set_index('DateTime', inplace=True)
df_merge.sort_index(inplace=True)
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-156-5e5d9ecf00df> in <module>
1 df_merge.set_index('DateTime', inplace=True)
2 df_merge.sort_index(inplace=True)
----> 3 df.merge.head(1)
AttributeError: 'function' object has no attribute 'head'
df_merge.head(1)
|
站点 |
压力 |
天气 |
气温 |
风向 |
最高温 |
最低温 |
温差 |
沙暴 |
雾 |
雨 |
雪 |
晴 |
rain_level |
snow_level |
东风 |
南风 |
西风 |
北风 |
year_week |
DateTime |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2018-01-01 |
站点4 |
0.40275 |
多云 |
1C~-4C |
东南风 微风 |
1.0 |
-4.0 |
5.0 |
False |
False |
False |
False |
False |
0.0 |
0.0 |
1.0 |
1.0 |
0.0 |
0.0 |
2018_1 |
def mask_fun_quantile(x):
return x.quantile(0.95)
# 错误写法
# df_merge.rolling('7D').transform(['mean', 'std', mask_fun_quantile, sum_rain_snow_days])
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-158-bdce6bad1ce3> in <module>
5
6
----> 7 df_merge.rolling('7D').transform(['mean', 'std', mask_fun_quantile, sum_rain_snow_days])
8
9
D:\Anaconda3\lib\site-packages\pandas\core\window\rolling.py in __getattr__(self, attr)
207
208 raise AttributeError(
--> 209 f"'{type(self).__name__}' object has no attribute '{attr}'"
210 )
211
AttributeError: 'Rolling' object has no attribute 'transform'
df_merge.groupby(['站点'])[['压力']].apply(lambda x:x.rolling('7D').mean()).head()
|
压力 |
DateTime |
|
2018-01-01 00:00:00 |
0.288625 |
2018-01-01 00:00:00 |
0.271875 |
2018-01-01 00:00:00 |
0.260625 |
2018-01-01 00:00:00 |
0.280875 |
2018-01-01 00:00:00 |
0.292500 |
... |
... |
2019-12-31 23:00:00 |
0.262194 |
2019-12-31 23:00:00 |
0.000000 |
2019-12-31 23:00:00 |
0.277319 |
2019-12-31 23:00:00 |
0.386888 |
2019-12-31 23:00:00 |
0.211321 |
525600 rows × 1 columns
df_merge.groupby(['站点'])[['压力']].apply(lambda x:x.rolling('7D').std()).tail()
|
压力 |
DateTime |
|
2019-12-31 23:00:00 |
0.018159 |
2019-12-31 23:00:00 |
0.000144 |
2019-12-31 23:00:00 |
0.028620 |
2019-12-31 23:00:00 |
0.040969 |
2019-12-31 23:00:00 |
0.059803 |
df_merge.groupby(['站点'])[['压力']].apply(lambda x:x.rolling('7D').apply(mask_fun_quantile)).head()
|
压力 |
DateTime |
|
2018-01-01 |
0.288625 |
2018-01-01 |
0.271875 |
2018-01-01 |
0.260625 |
2018-01-01 |
0.280875 |
2018-01-01 |
0.292500 |
# def sum_rain_snow_days(x):
# return x[x['雨']==True].shape[0] + x[x['雪']==True].shape[0]
for wea in ['雨', '雪']:
df_merge[wea] = df_merge[wea].apply(lambda x: 1 if x==True else 0)
df_merge['雨+雪'] = df_merge['雨'] + df_merge['雪']
df_merge.groupby(['站点'])[['雨+雪']].apply(lambda x:x.rolling('7D').sum()).head()
|
雨+雪 |
DateTime |
|
2018-01-01 |
0.0 |
2018-01-01 |
0.0 |
2018-01-01 |
0.0 |
2018-01-01 |
0.0 |
2018-01-01 |
0.0 |
- 当前时刻向前7日内,该站点同一整点时间水压的均值、标准差、0.95分位数
# 错误写法
# df_merge.rolling('7D').groupby([df_merge.DateTime.dt.hour])['压力'].transform(['mean', 'std', mask_fun_quantile])
df_merge['站点']
DateTime
2018-01-01 00:00:00 站点4
2018-01-01 00:00:00 站点22
2018-01-01 00:00:00 站点17
2018-01-01 00:00:00 站点21
2018-01-01 00:00:00 站点12
...
2019-12-31 23:00:00 站点7
2019-12-31 23:00:00 站点11
2019-12-31 23:00:00 站点30
2019-12-31 23:00:00 站点9
2019-12-31 23:00:00 站点6
Name: 站点, Length: 525600, dtype: object
df_merge['DateTime2'] = pd.to_datetime(df_merge.index)
df_merge.groupby(['站点', df_merge['DateTime2'].dt.hour])[['压力']].apply(lambda x:x.rolling('7D').mean()).head()
|
压力 |
DateTime |
|
2018-01-01 |
0.288625 |
2018-01-01 |
0.271875 |
2018-01-01 |
0.260625 |
2018-01-01 |
0.280875 |
2018-01-01 |
0.292500 |
df_merge.groupby(['站点', df_merge['DateTime2'].dt.hour])[['压力']].apply(lambda x:x.rolling('7D').std()).tail()
df_merge.groupby(['站点', df_merge['DateTime2'].dt.hour])[['压力']].apply(lambda x:x.rolling('7D').apply(mask_fun_quantile)).head()
- 当前时刻所在日的该站点水压最高值与最低值出现时刻的时间.
思路:
- 计算出最高值与最低值, 确定最高的和最低的,去重,然后两次join
df_merge['DateTime2']
DateTime
2018-01-01 00:00:00 2018-01-01 00:00:00
2018-01-01 00:00:00 2018-01-01 00:00:00
2018-01-01 00:00:00 2018-01-01 00:00:00
2018-01-01 00:00:00 2018-01-01 00:00:00
2018-01-01 00:00:00 2018-01-01 00:00:00
...
2019-12-31 23:00:00 2019-12-31 23:00:00
2019-12-31 23:00:00 2019-12-31 23:00:00
2019-12-31 23:00:00 2019-12-31 23:00:00
2019-12-31 23:00:00 2019-12-31 23:00:00
2019-12-31 23:00:00 2019-12-31 23:00:00
Name: DateTime2, Length: 525600, dtype: datetime64[ns]
press_max = df_merge.groupby(['站点',df_merge.DateTime2.dt.year.rename('year'), df_merge.DateTime2.dt.month.rename('mon'), df_merge.DateTime2.dt.day.rename('day')])[['压力']].transform(np.max)
press_min = df_merge.groupby(['站点',df_merge.DateTime2.dt.year.rename('year'), df_merge.DateTime2.dt.month.rename('mon'), df_merge.DateTime2.dt.day.rename('day')])[['压力']].transform(np.min)
press_max.head()
|
|
|
|
压力 |
站点 |
DateTime2 |
DateTime2 |
DateTime2 |
|
站点1 |
2018 |
1 |
1 |
0.300250 |
2 |
0.296500 |
3 |
0.311875 |
4 |
0.298750 |
5 |
0.294625 |
press_max['is_max'] = press_max['压力']==press_max['max']
press_max_filter = press_max[press_max['is_max']]
press_max_filter.drop_duplicates(keep='first')
press_max.index=press_max.index.map(lambda x : str(x[0])+'-'+str(x[1])+'-'+str(x[2]))
press_max_filter.index=press_max_filter.index.map(lambda x : str(x[0])+'-'+str(x[1])+'-'+str(x[2]))
press_max.join(press_max_filter, how='left')