电力负荷预测案例之数据预处理
1 课程概览
本课讲解电力负荷预测案例的数据预处理。包括开发通用工具包、数据格式化、时间排序、去除重复数据等。强调数据预处理在项目中的重要性。
2 核心概念与定义
- 通用工具包:
utils/common.py,数据预处理。 - 数据预处理:时间格式化、升序排列、去除重复。
- 训练集:
data/train.csv,需拆分训练集和测试集。 - 测试集:
data/test.csv,模拟项目上线后的真实测试集。 - 脱敏数据:隐藏单位,避免泄密风险。
3 算法与模型详解
3.1 开发通用工具包
文件:utils/common.py
功能:对数据做预处理
目的:
- 时间格式化
- 按照时间升序排列
- 对数据去除重复
3.2 数据集介绍
训练集:data/train.csv
- 数据量:约16753条(除第一行16752条)
- 时间范围:2013年 ~ 2015年7月31日
- 字段:time(时间)、power_load(电力负荷)
- 需要拆分训练集和测试集
测试集:data/test.csv
- 模拟项目上线后的真实测试集
- 纯新数据,未经过训练和预测
- 也有7月31号数据(与训练集重叠)
预测数据:
- 使用2015年8月1号以后的数据
- 避免训练集和测试集重叠
3.3 数据脱敏
说明:
- 数据是脱敏后的
- 没有说明单位
- 没有说明是省、市、县区还是变电站
- 避免泄密风险
实际应用:
- 未来到公司处理的数据类似
- 只不过会有单位
- 数据格式都一样
3.4 数据预处理函数
函数名:data_preprocessing
功能:
- 时间格式化
- 按时间升序排列
- 去除重复数据
参数:数据源
返回:处理后的结果
4 代码示例
import os
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# 1. 通用工具包
print("=== 1. 通用工具包 ===")
def data_preprocessing(data):
"""
数据预处理
Args:
data: 数据源
Returns:
处理后的数据
"""
# 1. 拷贝数据(防止修改原数据)
data = data.copy()
# 2. 时间格式化
data['time'] = pd.to_datetime(data['time'])
# 3. 按时间升序排列
data = data.sort_values(by='time').reset_index(drop=True)
# 4. 去除重复数据
data = data.drop_duplicates().reset_index(drop=True)
return data
# 2. 模拟数据
print("\n=== 2. 模拟数据 ===")
def generate_sample_data():
"""生成样本数据"""
np.random.seed(42)
# 生成数据(包含重复和无序)
dates = pd.date_range('2024-01-01', periods=100, freq='h')
power_load = np.random.randint(500, 1200, 100).astype(float)
data = pd.DataFrame({
'time': dates,
'power_load': power_load
})
# 添加重复数据
data = pd.concat([data, data.iloc[:5]], ignore_index=True)
# 打乱顺序
data = data.sample(frac=1, random_state=42).reset_index(drop=True)
return data
raw_data = generate_sample_data()
print(f"原始数据形状: {raw_data.shape}")
print(f"原始数据前5行:")
print(raw_data.head())
# 3. 数据预处理
print("\n=== 3. 数据预处理 ===")
processed_data = data_preprocessing(raw_data)
print(f"处理后数据形状: {processed_data.shape}")
print(f"处理后数据前5行:")
print(processed_data.head())
print(f"时间类型: {processed_data['time'].dtype}")
# 4. 数据集介绍
print("\n=== 4. 数据集介绍 ===")
def dataset_introduction():
"""数据集介绍"""
print("""
数据集介绍:
1. 训练集 (data/train.csv)
- 数据量: 约16753条
- 时间范围: 2013年 ~ 2015年7月31日
- 字段: time, power_load
- 用途: 拆分训练集和测试集
2. 测试集 (data/test.csv)
- 模拟项目上线后的真实测试集
- 纯新数据,未经过训练和预测
- 也有7月31号数据(与训练集重叠)
3. 预测数据
- 使用2015年8月1号以后的数据
- 避免训练集和测试集重叠
4. 数据脱敏
- 隐藏单位
- 避免泄密风险
- 实际应用中会有单位
""")
dataset_introduction()
# 5. 数据加载
print("\n=== 5. 数据加载 ===")
def load_data(train_path='data/train.csv', test_path='data/test.csv'):
"""加载数据"""
try:
train_data = pd.read_csv(train_path)
test_data = pd.read_csv(test_path)
print(f"训练集形状: {train_data.shape}")
print(f"测试集形状: {test_data.shape}")
return train_data, test_data
except FileNotFoundError as e:
print(f"文件未找到: {e}")
return None, None
# 6. 数据预处理流程
print("\n=== 6. 数据预处理流程 ===")
def preprocessing_pipeline(data):
"""数据预处理流程"""
print("原始数据:")
print(f" 形状: {data.shape}")
print(f" 时间类型: {data['time'].dtype}")
# 1. 时间格式化
data['time'] = pd.to_datetime(data['time'])
print(f"\n1. 时间格式化完成")
print(f" 时间类型: {data['time'].dtype}")
# 2. 按时间升序排列
data = data.sort_values(by='time').reset_index(drop=True)
print(f"\n2. 时间排序完成")
print(f" 时间范围: {data['time'].min()} ~ {data['time'].max()}")
# 3. 去除重复数据
before_count = len(data)
data = data.drop_duplicates().reset_index(drop=True)
after_count = len(data)
print(f"\n3. 去除重复完成")
print(f" 去除前: {before_count}条")
print(f" 去除后: {after_count}条")
print(f" 去除: {before_count - after_count}条")
return data
processed_data = preprocessing_pipeline(raw_data)
# 7. 数据验证
print("\n=== 7. 数据验证 ===")
def validate_data(data):
"""验证数据"""
print("数据验证:")
print(f" 形状: {data.shape}")
print(f" 列名: {list(data.columns)}")
print(f" 数据类型:\n{data.dtypes}")
print(f"\n 缺失值:\n{data.isnull().sum()}")
print(f"\n 描述统计:\n{data.describe()}")
# 时间连续性检查
time_diff = data['time'].diff().dropna()
print(f"\n 时间间隔统计:")
print(f" 最小间隔: {time_diff.min()}")
print(f" 最大间隔: {time_diff.max()}")
print(f" 平均间隔: {time_diff.mean()}")
validate_data(processed_data)
# 8. 数据分割
print("\n=== 8. 数据分割 ===")
def split_data(data, test_size=0.2):
"""分割数据"""
split_idx = int(len(data) * (1 - test_size))
train_data = data.iloc[:split_idx]
test_data = data.iloc[split_idx:]
print(f"训练集: {train_data.shape}")
print(f" 时间范围: {train_data['time'].min()} ~ {train_data['time'].max()}")
print(f"测试集: {test_data.shape}")
print(f" 时间范围: {test_data['time'].min()} ~ {test_data['time'].max()}")
return train_data, test_data
train_data, test_data = split_data(processed_data)
# 9. 可视化
print("\n=== 9. 可视化 ===")
def visualize_data(data):
"""可视化数据"""
plt.figure(figsize=(14, 10))
# 1. 电力负荷时序图
plt.subplot(2, 1, 1)
plt.plot(data['time'], data['power_load'], 'b-', linewidth=0.5)
plt.xlabel('时间')
plt.ylabel('电力负荷')
plt.title('电力负荷时序图')
plt.grid(True, alpha=0.3)
# 2. 电力负荷分布直方图
plt.subplot(2, 1, 2)
plt.hist(data['power_load'], bins=50, color='skyblue', edgecolor='black')
plt.xlabel('电力负荷')
plt.ylabel('频数')
plt.title('电力负荷分布')
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig('data_visualization.png', dpi=100)
print("数据可视化图已保存")
visualize_data(processed_data)
# 10. 完整预处理工具类
print("\n=== 10. 完整预处理工具类 ===")
def complete_common_utils():
"""完整预处理工具类"""
print("""
utils/common.py 完整代码:
import numpy as np
import pandas as pd
def data_preprocessing(data):
\"\"\"
数据预处理
Args:
data: 数据源
Returns:
处理后的数据
\"\"\"
# 1. 拷贝数据
data = data.copy()
# 2. 时间格式化
data['time'] = pd.to_datetime(data['time'])
# 3. 按时间升序排列
data = data.sort_values(by='time').reset_index(drop=True)
# 4. 去除重复数据
data = data.drop_duplicates().reset_index(drop=True)
return data
# 使用方法
if __name__ == '__main__':
data = pd.read_csv('data/train.csv')
processed_data = data_preprocessing(data)
print(processed_data.head())
""")
complete_common_utils()
# 11. 数据预处理总结
def preprocessing_summary():
"""数据预处理总结"""
print("=" * 50)
print("数据预处理总结")
print("=" * 50)
print("\n1. 通用工具包")
print(" utils/common.py")
print(" data_preprocessing函数")
print("\n2. 预处理步骤")
print(" 时间格式化")
print(" 按时间升序排列")
print(" 去除重复数据")
print("\n3. 数据集")
print(" 训练集: data/train.csv")
print(" 测试集: data/test.csv")
print(" 预测: 2015年8月1号以后")
print("\n4. 数据脱敏")
print(" 隐藏单位")
print(" 避免泄密")
print("\n" + "=" * 50)
print("数据预处理完成!")
print("=" * 50)
preprocessing_summary()
输出示例:
=== 2. 模拟数据 ===
原始数据形状: (105, 2)
=== 3. 数据预处理 ===
处理后数据形状: (100, 2)
时间类型: datetime64[ns]
=== 6. 数据预处理流程 ===
原始数据:
形状: (105, 2)
时间类型: object
1. 时间格式化完成
时间类型: datetime64[ns]
2. 时间排序完成
3. 去除重复完成
去除前: 105条
去除后: 100条
去除: 5条
5 重难点与易错提醒
- ❗重点:通用工具包放在
utils/common.py。 - ❗重点:数据预处理三步骤:格式化、排序、去重。
- ❗重点:预测使用2015年8月1号以后的数据。
- ❗重点:数据是脱敏的,没有单位。
- ⚠️易错:函数名不一致导致导包失败。
- ⚠️易错:忘记拷贝数据导致修改原数据。
- 💡深入理解:数据预处理是项目的基础。
6 课堂问答精选
Q: 数据预处理包括哪些步骤?
A: 数据预处理三步骤:
- 时间格式化:
pd.to_datetime() - 按时间升序排列:
sort_values() - 去除重复数据:
drop_duplicates()
Q: 为什么预测使用8月1号以后的数据?
A: 原因:
- 训练集和测试集都有7月31号数据
- 存在重叠
- 使用8月1号以后的数据避免重叠
- 模拟项目上线后的真实预测
7 本课小结
- 工具包:
utils/common.py,data_preprocessing函数。 - 步骤:时间格式化、升序排列、去除重复。
- 数据集:train.csv(训练)、test.csv(测试)。
- 预测:2015年8月1号以后数据。
- 脱敏:隐藏单位,避免泄密。
8 延伸思考与实践
- 实践:编写数据预处理函数。
- 预习:定义电力负荷模型类。
- 思考:如何处理时间不连续的数据?