3、Python 数据科学基础回顾:NumPy、Pandas、Matplotlib 快速上手

做功率预测,说白了就是跟数据打交道。

你拿到的原始数据,可能是几千行的时间戳和功率值,也可能是几十个传感器传回来的乱七八糟的表格。如果没有趁手的工具,光靠 Python 自带的列表和循环去处理,效率低得让人想砸键盘。

我个人习惯,一上来先把 NumPy、Pandas、Matplotlib 这三件套装好。它们就像是数据科学家的「瑞士军刀」——一个管数值计算,一个管表格操作,一个管可视化。今天我们就快速过一遍,保证你上手就能用。

核心知识体系

下面这张图,是我自己总结的「数据科学三件套」的协作关系。你看完就明白,为什么它们总是绑在一起出现。

数据科学三件套协作关系图 NumPy 多维数组 + 数学运算 底层计算引擎 Pandas DataFrame + 时间序列 数据处理中间层 Matplotlib 折线图 + 散点图 可视化输出层 典型工作流: 1. 用 Pandas 读取 CSV/Excel 数据 → 得到 DataFrame 2. 用 NumPy 对数值列做数学变换(归一化、差分) 3. 用 Matplotlib 画出功率曲线,看看有没有异常点 数据从原始表格 → 数值计算 → 可视化分析,一气呵成

3.1 NumPy:一切计算的基石

NumPy 的核心就一个东西:ndarray(N维数组)。

Python 自带的列表也能存数字,但做数学运算时慢得让人崩溃。NumPy 底层用 C 语言实现,速度能快几十倍。我在做风电功率预测时,要处理几十万条时间序列数据,用列表算一次滑动平均要等好几秒,换成 NumPy 几乎是瞬间完成。

我的习惯:只要涉及数值计算,第一件事就是把数据转成 NumPy 数组。哪怕只是做个加法。

import numpy as np

# 创建数组
arr = np.array([1, 2, 3, 4, 5])
print(arr)  # [1 2 3 4 5]

# 常用操作
print(arr.shape)      # (5,) —— 形状
print(arr.mean())     # 3.0 —— 均值
print(arr.std())      # 1.414 —— 标准差

# 向量化运算(这才是精髓)
arr2 = arr * 2 + 1
print(arr2)           # [3 5 7 9 11]

# 布尔索引(筛选数据)
mask = arr > 3
print(arr[mask])      # [4 5]

嗯,这里要注意:向量化运算是 NumPy 最强大的特性。你不需要写 for 循环,直接对整个数组做运算,代码又短又快。

我曾经踩过的坑:用 NumPy 做数组拼接时,忘记检查维度是否一致。有一次我把形状为 (100,) 和 (100,1) 的两个数组拼在一起,结果出来一个奇怪的结构,后续计算全错了。所以每次拼接前,我都会用 .shape 看一眼。

3.2 Pandas:表格数据的瑞士军刀

Pandas 的核心是两个东西:Series(一维)和 DataFrame(二维)。

说白了,DataFrame 就是一张 Excel 表格,有行有列,每列可以有不同的数据类型。功率预测的数据,通常就是这种结构:一列时间戳,一列功率值,可能还有几列风速、温度之类的特征。

import pandas as pd

# 读取 CSV 文件(实际项目中常用)
# df = pd.read_csv('power_data.csv')

# 这里我们手动创建一个示例
data = {
    'timestamp': ['2024-01-01 00:00', '2024-01-01 01:00', '2024-01-01 02:00'],
    'power': [120.5, 135.2, 98.7],
    'wind_speed': [5.2, 6.1, 4.3]
}
df = pd.DataFrame(data)
print(df)

# 查看基本信息
print(df.info())        # 列名、非空数量、数据类型
print(df.describe())    # 统计摘要(均值、标准差、四分位数等)

# 选择列
print(df['power'])      # 单列,返回 Series
print(df[['power', 'wind_speed']])  # 多列,返回 DataFrame

# 条件筛选
high_power = df[df['power'] > 100]
print(high_power)

我个人觉得,Pandas 最牛的地方是时间序列处理。功率预测的数据几乎都是时间序列,Pandas 对时间索引的支持非常完善。

# 把时间戳列设为索引
df['timestamp'] = pd.to_datetime(df['timestamp'])
df.set_index('timestamp', inplace=True)

# 按小时重采样(比如把15分钟数据聚合成小时数据)
# hourly = df.resample('H').mean()

# 滑动窗口(计算滚动平均)
df['power_smooth'] = df['power'].rolling(window=3).mean()
print(df)

避坑指南:我曾经在处理真实数据时,发现时间戳列里有空值和重复值。Pandas 的 dropna()drop_duplicates() 是救星。拿到数据后,我建议先做这两步清洗。

3.3 Matplotlib:让数据说话

数据算完了,不画出来看看,你根本不知道它长什么样。

Matplotlib 是 Python 最经典的可视化库。虽然现在有很多花哨的替代品(比如 Seaborn、Plotly),但 Matplotlib 依然是底层基础,学会了它,其他库上手就很快。

import matplotlib.pyplot as plt

# 简单折线图
x = [1, 2, 3, 4, 5]
y = [120, 135, 98, 150, 110]

plt.plot(x, y, marker='o', linestyle='-', color='b')
plt.title('功率变化曲线')
plt.xlabel('时间点')
plt.ylabel('功率 (kW)')
plt.grid(True)
plt.show()

你想想看,如果数据里有异常点,比如某个时刻功率突然降到 0,画成图一眼就能看出来。光看表格里的数字,你可能要盯半天才发现。

实际项目中的标准流程:

  1. 用 Pandas 读取数据
  2. 用 NumPy 做归一化、差分等预处理
  3. 用 Matplotlib 画出原始曲线和预处理后的曲线,对比效果
  4. 确认数据没问题后,再喂给深度学习模型
# 更完整的示例:画子图对比原始数据和归一化后的数据
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

# 模拟数据
np.random.seed(42)
dates = pd.date_range('2024-01-01', periods=100, freq='H')
power = 100 + 20 * np.sin(np.linspace(0, 4*np.pi, 100)) + np.random.normal(0, 5, 100)

df = pd.DataFrame({'timestamp': dates, 'power': power})
df.set_index('timestamp', inplace=True)

# 归一化
power_norm = (df['power'] - df['power'].mean()) / df['power'].std()

# 画图
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 6))

ax1.plot(df.index, df['power'], color='#4A90D9')
ax1.set_title('原始功率数据')
ax1.set_ylabel('功率 (kW)')
ax1.grid(True)

ax2.plot(df.index, power_norm, color='#E67E22')
ax2.set_title('归一化后的功率数据')
ax2.set_ylabel('标准化值')
ax2.grid(True)

plt.tight_layout()
plt.show()

我曾经犯过的错:画图时忘记设置 figsize,默认的图太小,导致曲线挤在一起,根本看不清细节。后来我习惯先写 plt.figure(figsize=(12, 5)),把图调大一点。另外,中文显示问题也坑过我——记得加上 plt.rcParams['font.sans-serif'] = ['SimHei'],否则中文会变成方框。

3.4 三件套配合实战:快速检查数据质量

最后,我分享一个我在项目中常用的「数据快速检查」脚本。它把三件套串起来,几分钟就能摸清一批数据的底细。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

def quick_check(df, col_name):
    """
    快速检查某列数据的质量
    """
    # 1. 基本统计
    print(f"=== {col_name} 数据概览 ===")
    print(df[col_name].describe())
    
    # 2. 缺失值
    missing = df[col_name].isnull().sum()
    print(f"缺失值数量: {missing}")
    
    # 3. 异常值检测(3σ原则)
    mean = df[col_name].mean()
    std = df[col_name].std()
    outliers = df[(df[col_name] < mean - 3*std) | (df[col_name] > mean + 3*std)]
    print(f"异常值数量 (3σ): {len(outliers)}")
    
    # 4. 可视化
    fig, axes = plt.subplots(1, 2, figsize=(12, 4))
    
    # 折线图
    axes[0].plot(df.index, df[col_name], color='#4A90D9', linewidth=0.8)
    axes[0].set_title(f'{col_name} 时间序列')
    axes[0].grid(True)
    
    # 直方图
    axes[1].hist(df[col_name].dropna(), bins=30, color='#27AE60', alpha=0.7)
    axes[1].set_title(f'{col_name} 分布')
    axes[1].grid(True)
    
    plt.tight_layout()
    plt.show()

# 使用示例
# quick_check(df, 'power')

这个函数我几乎每个项目都会用。拿到数据后先跑一遍,心里就有数了——有没有缺失值?有没有离谱的异常点?分布是正态的还是偏态的?这些信息直接决定了后续的预处理策略。

好了,NumPy、Pandas、Matplotlib 的基础就回顾到这里。记住:这三样东西不是孤立学的,它们是配合使用的。你处理功率预测数据时,大概率会反复在它们之间切换。多练几次,形成肌肉记忆,后面做深度学习模型时就会顺手很多。


专注资料整理