2. Python数据分析基础回顾:NumPy数组操作、Pandas DataFrame基础、数据清洗与缺失值处理

在构建异常检测与实时监控大屏之前,必须夯实Python数据分析的核心基础。本章将系统回顾NumPy数组操作、Pandas DataFrame基础以及数据清洗与缺失值处理三大模块,为后续的时序数据处理、统计建模与可视化输出奠定坚实的技术底座。

2.1 NumPy数组操作

NumPy是Python科学计算的基石,其核心数据结构ndarray提供了高效的向量化运算能力。在异常检测场景中,NumPy常用于滑动窗口计算、统计特征提取与矩阵运算。

2.1.1 数组创建与基本属性

方法 说明 示例
np.array() 从列表或元组创建数组 np.array([1,2,3])
np.zeros() 创建全零数组 np.zeros((3,4))
np.ones() 创建全一数组 np.ones((2,3))
np.arange() 创建等差序列 np.arange(0,10,2)
np.random.randn() 标准正态分布随机数 np.random.randn(100)

关键属性:ndim(维度)、shape(形状)、dtype(数据类型)、size(元素总数)。

2.1.2 向量化运算与广播机制

向量化运算是NumPy性能的核心优势,避免使用Python原生循环。广播机制允许不同形状的数组进行算术运算。

import numpy as np

# 向量化运算
data = np.array([10, 20, 30, 40, 50])
normalized = (data - data.mean()) / data.std()

# 广播机制
matrix = np.ones((4, 3))
row_mean = np.array([1, 2, 3])
result = matrix * row_mean  # 每行乘以row_mean

# 条件筛选(异常检测常用)
threshold = 35
outliers = data[data > threshold]
print(outliers)  # [40 50]

2.1.3 统计函数与聚合操作

异常检测中频繁使用NumPy的统计函数计算数据的分布特征。

函数 说明 异常检测用途
np.mean() 均值 中心趋势度量
np.std() 标准差 离散程度度量
np.percentile() 百分位数 箱线图异常阈值
np.median() 中位数 稳健中心估计
np.diff() 差分 突变检测

实战提示:在实时监控场景中,使用np.lib.stride_tricks.sliding_window_view()可以高效生成滑动窗口数据,用于计算滚动统计量。

NumPy数组操作流程 原始数据 数组创建 向量化运算 统计聚合 异常标记 核心:利用广播机制与向量化运算,避免Python原生循环,提升计算效率

2.2 Pandas DataFrame基础

Pandas是数据分析的核心工具,DataFrame作为二维表格数据结构,天然适配时间序列监控数据的存储与操作。在异常检测大屏中,DataFrame负责数据加载、切片、聚合与可视化准备。

2.2.1 DataFrame创建与基本操作

import pandas as pd
import numpy as np

# 从字典创建DataFrame
df = pd.DataFrame({
    'timestamp': pd.date_range('2024-01-01', periods=5, freq='H'),
    'cpu_usage': [45.2, 67.8, 92.1, 55.3, 78.9],
    'memory_usage': [60.1, 72.5, 88.3, 65.4, 81.2],
    'disk_io': [120, 340, 560, 210, 430]
})

# 查看基本信息
print(df.info())
print(df.describe())

# 列选择与过滤
high_cpu = df[df['cpu_usage'] > 80]
print(high_cpu)

2.2.2 索引操作与时间序列

时间序列索引是监控数据的核心特征,Pandas提供了强大的时间索引操作能力。

操作 方法 示例
设置时间索引 set_index() df.set_index('timestamp')
时间范围切片 loc[] df.loc['2024-01-01 02:00':'2024-01-01 04:00']
重采样 resample() df.resample('10min').mean()
滚动窗口 rolling() df['cpu_usage'].rolling(3).mean()

注意:时间索引必须为DatetimeIndex类型,否则切片和重采样会失败。使用pd.to_datetime()进行类型转换。

2.2.3 分组聚合与多维度分析

在监控大屏中,经常需要按主机、服务或地域进行分组统计。

# 模拟多主机数据
df_multi = pd.DataFrame({
    'host': ['server-A']*3 + ['server-B']*3 + ['server-C']*3,
    'cpu': np.random.uniform(30, 95, 9),
    'mem': np.random.uniform(40, 90, 9)
})

# 分组聚合
grouped = df_multi.groupby('host').agg({
    'cpu': ['mean', 'max', 'std'],
    'mem': ['mean', 'max', 'std']
})
print(grouped)
Pandas DataFrame数据处理流程 数据源 DataFrame加载 数据清洗 数据转换 分组聚合 可视化输出 DataFrame是监控大屏数据流的中心枢纽,连接数据源与可视化层

2.3 数据清洗与缺失值处理

真实监控数据往往存在缺失值、异常值和重复记录。数据清洗是异常检测的前置步骤,直接影响模型准确性与大屏展示效果。

2.3.1 缺失值检测与统计

# 创建含缺失值的示例数据
df_raw = pd.DataFrame({
    'time': pd.date_range('2024-01-01', periods=10, freq='5min'),
    'cpu': [45.2, np.nan, 67.8, 92.1, np.nan, 55.3, 78.9, 88.2, np.nan, 62.4],
    'mem': [60.1, 72.5, np.nan, 88.3, 65.4, np.nan, 81.2, 75.6, 90.1, 68.7]
})

# 缺失值检测
print(df_raw.isnull().sum())
print(df_raw.isnull().mean() * 100)  # 缺失比例

2.3.2 缺失值处理策略

策略 方法 适用场景 代码示例
删除缺失行 dropna() 缺失比例低(<5%) df.dropna()
固定值填充 fillna() 已知默认值 df.fillna(0)
均值/中位数填充 fillna() 数值型数据 df.fillna(df.mean())
前向填充 ffill() 时间序列 df.ffill()
后向填充 bfill() 时间序列 df.bfill()
插值法 interpolate() 平滑趋势数据 df.interpolate()

最佳实践:在实时监控场景中,优先使用前向填充(ffill())处理短暂缺失,因为监控数据通常具有时间连续性;对于长时间缺失,建议标记为异常而非填充。

2.3.3 异常值检测与处理

异常值检测是数据清洗的重要环节,常用方法包括Z-score和IQR(四分位距)法。

# Z-score方法
from scipy import stats
z_scores = np.abs(stats.zscore(df_raw['cpu'].dropna()))
threshold = 3
outliers_z = df_raw['cpu'][z_scores > threshold]

# IQR方法
Q1 = df_raw['cpu'].quantile(0.25)
Q3 = df_raw['cpu'].quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
outliers_iqr = df_raw['cpu'][(df_raw['cpu'] < lower_bound) | (df_raw['cpu'] > upper_bound)]

print(f"Z-score异常值: {outliers_z.tolist()}")
print(f"IQR异常值: {outliers_iqr.tolist()}")

2.3.4 重复数据处理

# 检测与删除重复行
df_dup = df_raw.append(df_raw.iloc[0])  # 模拟重复
print(f"重复行数: {df_dup.duplicated().sum()}")
df_clean = df_dup.drop_duplicates()

# 基于特定列去重
df_clean_col = df_dup.drop_duplicates(subset=['time'])
数据清洗与缺失值处理流程 原始监控数据 缺失? 缺失值处理 异常值检测 重复数据处理 清洗后数据 清洗策略选择:缺失比例低→删除;时间连续→前向填充;异常值→IQR或Z-score

实战案例:在CPU监控数据中,若某时间点缺失值超过连续3个采样点,建议标记为“数据中断”异常,而非简单填充。这有助于区分传感器故障与真实负载波动。

2.4 综合实战:监控数据预处理流水线

将上述知识点整合为一条完整的监控数据预处理流水线,为后续异常检测模型提供干净、规范的数据输入。

def preprocess_monitor_data(df, time_col='timestamp', value_cols=None):
    """
    监控数据预处理流水线
    参数:
        df: 原始DataFrame
        time_col: 时间列名
        value_cols: 需要处理的数值列列表
    返回:
        清洗后的DataFrame
    """
    if value_cols is None:
        value_cols = df.select_dtypes(include=[np.number]).columns.tolist()

    # 1. 时间列处理
    df[time_col] = pd.to_datetime(df[time_col])
    df = df.set_index(time_col).sort_index()

    # 2. 缺失值处理(前向填充,限制连续填充3个)
    for col in value_cols:
        df[col] = df[col].ffill(limit=3)

    # 3. 异常值处理(IQR方法)
    for col in value_cols:
        Q1 = df[col].quantile(0.25)
        Q3 = df[col].quantile(0.75)
        IQR = Q3 - Q1
        lower = Q1 - 1.5 * IQR
        upper = Q3 + 1.5 * IQR
        df[col] = df[col].clip(lower, upper)

    # 4. 重复索引处理
    df = df[~df.index.duplicated(keep='first')]

    return df.reset_index()

# 使用示例
df_clean = preprocess_monitor_data(df_raw)
print(df_clean.head())

生产环境注意:上述流水线适用于离线批处理场景。在实时监控大屏中,建议使用流式处理框架(如Kafka + Flink)配合Pandas进行微批次清洗,避免全量数据重算。