电力负荷预测案例之查看数据整体和各小时负荷分布
1 课程概览
本课讲解电力负荷预测案例的数据分布查看。包括查看数据整体分布、负荷整体分布、各小时平均负荷分布等。通过可视化分析数据特征。
2 核心概念与定义
- analysis_data:查看数据分布的函数。
- 数据整体分布:使用
info()查看。 - 负荷整体分布:直方图。
- 各小时平均负荷:按小时分组求平均。
- 子图:
add_subplot()添加子图。
3 算法与模型详解
3.1 analysis_data函数
功能:查看数据分布
步骤:
- 查看数据整体分布
- 查看负荷整体分布
- 查看各小时平均负荷分布
3.2 查看数据整体分布
方法:data.info()
信息:
- 数据条数:16752条
- 字段:time(object)、power_load(float)
- 数据类型
- 内存占用
3.3 查看负荷整体分布
方法:直方图
说明:
- 查看power_load的分布
- 使用
plt.hist()
3.4 查看各小时平均负荷
方法:按小时分组求平均
步骤:
- 提取hour特征
- 按hour分组
- 求平均值
- 绘制柱状图
3.5 子图绘制
画布:plt.figure(figsize=(20, 40))
子图:
add_subplot(4, 1, 1):4行1列第1个add_subplot(4, 1, 2):4行1列第2个- 等等
说明:
- 画布尺寸:宽20,长40
- 4个子图垂直排列
4 代码示例
import os
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import logging
# 解决中文乱码
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 1. 日志工具类
print("=== 1. 日志工具类 ===")
class LogUtils:
"""日志工具类"""
def __init__(self, root_path='./', log_name='project', level=logging.INFO):
self.logger = logging.getLogger(log_name)
self.logger.setLevel(level)
if not self.logger.handlers:
log_dir = os.path.join(root_path, 'log')
os.makedirs(log_dir, exist_ok=True)
log_file = os.path.join(log_dir, f'{log_name}.log')
file_handler = logging.FileHandler(log_file, encoding='utf-8')
file_handler.setLevel(level)
console_handler = logging.StreamHandler()
console_handler.setLevel(level)
formatter = logging.Formatter(
'%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
file_handler.setFormatter(formatter)
console_handler.setFormatter(formatter)
self.logger.addHandler(file_handler)
self.logger.addHandler(console_handler)
def get_log(self):
return self.logger
# 2. 生成模拟数据
print("\n=== 2. 生成模拟数据 ===")
def generate_power_load_data(n_days=30):
"""生成电力负荷数据"""
np.random.seed(42)
dates = pd.date_range('2024-01-01', periods=n_days*24, freq='h')
power_load = []
for date in dates:
hour = date.hour
dayofweek = date.dayofweek
month = date.month
# 基础负荷
if 0 <= hour < 6:
base_load = 500
elif 6 <= hour < 9:
base_load = 800
elif 9 <= hour < 17:
base_load = 1000
elif 17 <= hour < 21:
base_load = 1200
else:
base_load = 700
# 周末调整
if dayofweek >= 5:
base_load *= 0.8
# 季节调整
if month in [12, 1, 2]:
base_load *= 1.2
elif month in [6, 7, 8]:
base_load *= 1.1
load = base_load + np.random.normal(0, 50)
power_load.append(max(100, load))
data = pd.DataFrame({
'time': dates,
'power_load': power_load
})
return data
data = generate_power_load_data(n_days=30)
print(f"数据形状: {data.shape}")
# 3. analysis_data函数
print("\n=== 3. analysis_data函数 ===")
def analysis_data(data):
"""
查看数据分布
Args:
data: 数据源
"""
# 2.1 为了防止修改原数据,做一次拷贝
analysis_data = data.copy()
# 2.2 查看数据整体分布
print("--- 查看数据整体分布 ---")
print(analysis_data.info())
# 2.3 查看负荷整体分布(直方图)
print("\n--- 查看负荷整体分布 ---")
# 创建画布
fig = plt.figure(figsize=(20, 40))
# 子图1:负荷整体分布(直方图)
ax1 = fig.add_subplot(4, 1, 1)
ax1.hist(analysis_data['power_load'], bins=50, color='skyblue', edgecolor='black')
ax1.set_xlabel('电力负荷')
ax1.set_ylabel('频数')
ax1.set_title('负荷整体分布')
ax1.grid(True, alpha=0.3)
# 2.4 查看各小时平均负荷分布
print("\n--- 查看各小时平均负荷分布 ---")
# 提取hour特征
analysis_data['hour'] = analysis_data['time'].dt.hour
# 按小时分组求平均
hourly_avg = analysis_data.groupby('hour')['power_load'].mean()
print("各小时平均负荷:")
for hour in range(24):
avg = hourly_avg.iloc[hour] if hour < len(hourly_avg) else 0
print(f" {hour:2d}时: {avg:.2f}")
# 子图2:各小时平均负荷(柱状图)
ax2 = fig.add_subplot(4, 1, 2)
ax2.bar(hourly_avg.index, hourly_avg.values, color='lightgreen', edgecolor='black')
ax2.set_xlabel('小时')
ax2.set_ylabel('平均负荷')
ax2.set_title('各小时平均负荷分布')
ax2.set_xticks(range(24))
ax2.grid(True, alpha=0.3)
# 子图3:负荷时序图
ax3 = fig.add_subplot(4, 1, 3)
ax3.plot(analysis_data['time'], analysis_data['power_load'], 'b-', linewidth=0.5)
ax3.set_xlabel('时间')
ax3.set_ylabel('电力负荷')
ax3.set_title('负荷时序图')
ax3.grid(True, alpha=0.3)
# 子图4:负荷箱线图(按小时)
ax4 = fig.add_subplot(4, 1, 4)
box_data = [analysis_data[analysis_data['hour'] == h]['power_load'].values for h in range(24)]
ax4.boxplot(box_data, labels=range(24))
ax4.set_xlabel('小时')
ax4.set_ylabel('电力负荷')
ax4.set_title('各小时负荷箱线图')
ax4.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig('data_distribution.png', dpi=100)
print("\n数据分布图已保存: data_distribution.png")
return analysis_data
# 4. 调用analysis_data
print("\n=== 4. 调用analysis_data ===")
result = analysis_data(data)
# 5. 数据分析详解
print("\n=== 5. 数据分析详解 ===")
def data_analysis_details(data):
"""数据分析详解"""
print("--- 1. 数据整体信息 ---")
print(f"数据形状: {data.shape}")
print(f"数据类型:\n{data.dtypes}")
print(f"\n描述统计:\n{data.describe()}")
print("\n--- 2. 负荷统计 ---")
print(f"最小负荷: {data['power_load'].min():.2f}")
print(f"最大负荷: {data['power_load'].max():.2f}")
print(f"平均负荷: {data['power_load'].mean():.2f}")
print(f"中位数: {data['power_load'].median():.2f}")
print(f"标准差: {data['power_load'].std():.2f}")
print("\n--- 3. 各小时统计 ---")
data['hour'] = data['time'].dt.hour
hourly_stats = data.groupby('hour')['power_load'].agg(['mean', 'std', 'min', 'max'])
print("各小时统计:")
for hour in range(24):
if hour < len(hourly_stats):
stats = hourly_stats.iloc[hour]
print(f" {hour:2d}时: 均值={stats['mean']:.2f}, "
f"标准差={stats['std']:.2f}, "
f"最小={stats['min']:.2f}, "
f"最大={stats['max']:.2f}")
data_analysis_details(data)
# 6. 可视化详解
print("\n=== 6. 可视化详解 ===")
def visualization_details(data):
"""可视化详解"""
print("""
可视化内容:
1. 负荷整体分布(直方图)
- 查看负荷的分布情况
- 了解负荷的集中区间
- 发现异常值
2. 各小时平均负荷(柱状图)
- 查看一天内的负荷变化
- 发现高峰和低谷时段
- 了解用电规律
3. 负荷时序图
- 查看负荷随时间变化
- 发现趋势和周期性
- 了解数据整体走势
4. 各小时负荷箱线图
- 查看各小时负荷分布
- 发现异常值
- 了解各小时负荷的离散程度
""")
visualization_details(data)
# 7. 数据分析结论
print("\n=== 7. 数据分析结论 ===")
def analysis_conclusions(data):
"""数据分析结论"""
data = data.copy()
data['hour'] = data['time'].dt.hour
hourly_avg = data.groupby('hour')['power_load'].mean()
# 找高峰和低谷
peak_hour = hourly_avg.idxmax()
peak_load = hourly_avg.max()
valley_hour = hourly_avg.idxmin()
valley_load = hourly_avg.min()
print(f"""
数据分析结论:
1. 数据量
- 共{len(data)}条数据
- 时间范围: {data['time'].min()} ~ {data['time'].max()}
2. 负荷分布
- 最小负荷: {data['power_load'].min():.2f}
- 最大负荷: {data['power_load'].max():.2f}
- 平均负荷: {data['power_load'].mean():.2f}
3. 用电规律
- 高峰时段: {peak_hour}时 (负荷: {peak_load:.2f})
- 低谷时段: {valley_hour}时 (负荷: {valley_load:.2f})
4. 建议
- 高峰时段注意电力调度
- 低谷时段可以安排储能
- 关注异常值
""")
analysis_conclusions(data)
# 8. 完整analysis_data代码
print("\n=== 8. 完整analysis_data代码 ===")
def complete_analysis_code():
"""完整analysis_data代码"""
print("""
def analysis_data(data):
\"\"\"查看数据分布\"\"\"
# 1. 拷贝数据
analysis_data = data.copy()
# 2. 查看数据整体分布
print(analysis_data.info())
# 3. 创建画布
fig = plt.figure(figsize=(20, 40))
# 4. 子图1:负荷整体分布(直方图)
ax1 = fig.add_subplot(4, 1, 1)
ax1.hist(analysis_data['power_load'], bins=50)
ax1.set_title('负荷整体分布')
# 5. 提取hour特征
analysis_data['hour'] = analysis_data['time'].dt.hour
# 6. 按小时分组求平均
hourly_avg = analysis_data.groupby('hour')['power_load'].mean()
# 7. 子图2:各小时平均负荷(柱状图)
ax2 = fig.add_subplot(4, 1, 2)
ax2.bar(hourly_avg.index, hourly_avg.values)
ax2.set_title('各小时平均负荷分布')
# 8. 子图3:负荷时序图
ax3 = fig.add_subplot(4, 1, 3)
ax3.plot(analysis_data['time'], analysis_data['power_load'])
ax3.set_title('负荷时序图')
# 9. 子图4:各小时负荷箱线图
ax4 = fig.add_subplot(4, 1, 4)
box_data = [analysis_data[analysis_data['hour'] == h]['power_load'].values
for h in range(24)]
ax4.boxplot(box_data, labels=range(24))
ax4.set_title('各小时负荷箱线图')
plt.tight_layout()
plt.savefig('data_distribution.png', dpi=100)
return analysis_data
""")
complete_analysis_code()
# 9. 总结
def analysis_summary():
"""分析总结"""
print("=" * 50)
print("数据分布查看总结")
print("=" * 50)
print("\n1. 函数名")
print(" analysis_data")
print("\n2. 步骤")
print(" 拷贝数据")
print(" 查看整体分布(info)")
print(" 查看负荷分布(直方图)")
print(" 查看各小时平均(柱状图)")
print("\n3. 画布")
print(" figsize=(20, 40)")
print(" 4个子图垂直排列")
print("\n4. 子图")
print(" add_subplot(4, 1, n)")
print("\n" + "=" * 50)
print("数据分布查看完成!")
print("=" * 50)
analysis_summary()
输出示例:
=== 3. analysis_data函数 ===
--- 查看数据整体分布 ---
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 720 entries, 0 to 719
Data columns (total 2 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 time 720 non-null datetime64[ns]
1 power_load 720 non-null float64
dtypes: datetime64[ns](1), float64(1)
--- 查看各小时平均负荷分布 ---
各小时平均负荷:
0时: 524.56
1时: 489.12
...
23时: 712.34
=== 7. 数据分析结论 ===
高峰时段: 18时 (负荷: 1180.45)
低谷时段: 3时 (负荷: 485.67)
5 重难点与易错提醒
- ❗重点:
analysis_data函数查看数据分布。 - ❗重点:先拷贝数据防止修改原数据。
- ❗重点:画布尺寸
figsize=(20, 40)。 - ❗重点:子图用
add_subplot(4, 1, n)。 - ⚠️易错:忘记拷贝数据。
- ⚠️易错:子图位置参数错误。
- 💡深入理解:数据分布分析是特征工程的基础。
6 课堂问答精选
Q: analysis_data函数的作用是什么?
A: 作用:
- 查看数据整体分布(info)
- 查看负荷整体分布(直方图)
- 查看各小时平均负荷(柱状图)
- 查看负荷时序图
- 查看各小时负荷箱线图
Q: 为什么要先拷贝数据?
A: 原因:
- 防止修改原数据
- 保持数据源不变
- 避免副作用
7 本课小结
- 函数:
analysis_data查看数据分布。 - 步骤:拷贝、info、直方图、柱状图。
- 画布:
figsize=(20, 40),4个子图。 - 子图:
add_subplot(4, 1, n)。 - 分析:发现高峰低谷时段。
8 延伸思考与实践
- 实践:运行analysis_data函数。
- 预习:按照月份、假日可视化数据。
- 思考:如何根据数据分布设计特征?