【20年12月DW打卡】joyful-pandas - 期末task11 - 综合练习

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')
posted @ 2021-01-13 22:26  山枫叶纷飞  阅读(164)  评论(0编辑  收藏  举报