
本文介绍如何使用 Pandas 对高频采样频谱数据进行时间维度下采样,将原始 0.25 秒间隔的列压缩为 1 秒间隔(即每 4 列合并为 1 列),核心方法是利用 .resample() 配合时间索引转置操作,兼顾准确性与可读性。
本文介绍如何使用 pandas 对高频采样频谱数据进行时间维度下采样,将原始 0.25 秒间隔的列压缩为 1 秒间隔(即每 4 列合并为 1 列),核心方法是利用 `.resample()` 配合时间索引转置操作,兼顾准确性与可读性。
在处理射电信号探测器采集的频谱数据时,常见结构为:行表示频率通道(200 行),列表示时间采样点(3600 列,每列对应 0.25 秒)。当业务需求要求将时间分辨率从 0.25 秒降低至 1 秒(即降为原分辨率的 1/4),本质是将每连续 4 列按时间对齐后取均值,生成 900 列新数据。
Pandas 提供了优雅且高性能的解决方案——resample() 方法,但需注意其设计前提:时间信息必须作为索引(而非普通列),且 resample 默认作用于行方向(即对时间索引重采样)。由于你的原始数据中时间信息隐含在列名中(如第 1 列 = t=0.0s,第 2 列 = t=0.25s…),因此关键步骤是:
-
为列构建时间索引:将列名转换为
DatetimeIndex,频率设为"250ms"; -
转置数据以适配 resample:
resample期望时间索引在行上,故先.T将时间列变为行索引; -
执行重采样与聚合:调用
.resample("1s").mean(),自动按 1 秒窗口分组并计算均值; -
转回原始结构:再次
.T恢复“频率为行、时间为列为”的格式。
以下是完整可运行示例:
import pandas as pd
import numpy as np
# 1. 构造模拟数据(200 频率通道 × 3600 时间点,0.25s 间隔)
count = 3600
time_index = pd.date_range("2025-04-01", periods=count, freq="250ms")
df = pd.DataFrame({
f"freq {i}MHz": np.random.randn(count) * 100
for i in range(1, 201)
}, index=time_index).T # 转置:频率为行,时间为列
# 2. 下采样:每 4 列(1 秒)合并为 1 列
df_downsampled = df.T.resample("1s").mean().T
print(f"原始形状: {df.shape}") # (200, 3600)
print(f"下采样后形状: {df_downsampled.shape}") # (200, 900)
✅ 为什么推荐 resample 而非手动切片?
- 自动处理边界对齐(如时间戳是否严格等距);
- 支持多种聚合函数(
.mean(),.max(),.std()等); - 兼容缺失值(
skipna=True默认); - 性能优于循环或
groupby手动分组。
⚠️ 注意事项:
- 若原始 CSV 中列名并非时间戳(如
"col_0","col_1"),需先用pd.date_range(...)重建列索引:df.columns = pd.date_range("2025-04-01", periods=len(df.columns), freq="250ms") -
resample要求索引单调递增且无重复,建议加载后校验:df.columns.is_monotonic_increasing; - 若需保留原始列名映射(如记录每组包含哪些原始列),可结合
pd.Grouper或自定义分组逻辑,但对标准等间隔场景非必需。
通过该方法,你可在一行核心代码内完成专业级时间下采样,既满足工程精度要求,又保持代码简洁可维护。










