使用Pandas插值非均匀时间序列时结果全为NaN的问题排查
非均匀时间序列插值全为NaN的问题分析与解决
我有多组非均匀时间步长的测量值时间序列,尝试用Python Pandas将其插值为固定10秒时间步长,但插值结果全为NaN。数据片段如下:
Timestamp,Value 2023-05-20T22:00:04.023Z,102 2023-05-20T22:00:14.033Z,100 2023-05-20T22:00:24.074Z,99 2023-05-20T22:00:35.484Z,99 2023-05-20T22:00:44.029Z,102 2023-05-20T22:00:54.054Z,100 2023-05-20T22:01:04.026Z,99 2023-05-20T22:01:14.029Z,103 2023-05-20T22:01:24.054Z,99 2023-05-20T22:01:34.022Z,98 2023-05-20T22:01:44.026Z,99 2023-05-20T22:01:54.062Z,100 2023-05-20T22:02:04.025Z,125
使用的Python脚本如下(调用interpolate方法前一切正常):
import pandas as pd Power_curr = pd.read_csv("pathtodata.csv",parse_dates=['Timestamp']) # Convert the 'Timestamp' column to datetime format Power_curr['Timestamp'] = pd.to_datetime(Power_curr['Timestamp']) # timestamp is index Power_curr.set_index('Timestamp', inplace=True) # Find start end end, round to 10 s start_time = Power_curr.index.min().ceil('10s') end_time = Power_curr.index.max().floor('10s') # Create new timestamp series new_time_index = pd.date_range(start=start_time, end=end_time, freq='10s') # Create new data frame and interpolate into new timestamps Power_curr_interpolated = Power_curr.reindex(new_time_index).interpolate(method='time')
已尝试的操作:
- 尝试过'linear'、'nearest'等不同插值方法
- 确认new_time_index为正确的datetime类型
- 检查Pandas版本为v2.2.2
- 尝试用resample('10s').mean()替代,结果无NaN但数值异常不随时间变化
- 查阅过相关Stack Overflow帖子但未找到解决方案
问题原因
核心问题是new_time_index的所有时间点和原数据的索引完全不重合,导致reindex(new_time_index)后整个DataFrame全为NaN,插值没有任何有效原始数据可以参考:
- 原数据的时间都是xx:xx:04、xx:xx:14这类非整10秒的点,而你用
ceil('10s')和floor('10s')生成的新索引全是整10秒(如22:00:10、22:00:20...); reindex会用新索引重新匹配数据,新索引里没有原数据的任何时间点,所以所有行都变成NaN,后续插值自然无法生效。
解决方法
方法1:保留原始数据点后插值
先创建包含原始索引和目标10秒索引的联合索引,确保原始有效数据被保留,再插值提取目标结果:
import pandas as pd Power_curr = pd.read_csv("pathtodata.csv", parse_dates=['Timestamp']) Power_curr.set_index('Timestamp', inplace=True) # 调整起止时间,确保覆盖原始数据的完整范围 start_time = Power_curr.index.min().floor('10s') end_time = Power_curr.index.max().ceil('10s') new_time_index = pd.date_range(start=start_time, end=end_time, freq='10s') # 合并原始索引和新索引,保留所有有效数据点 combined_index = Power_curr.index.union(new_time_index) # 重新索引后插值,最后提取10秒间隔的结果 Power_curr_full = Power_curr.reindex(combined_index) Power_curr_interpolated = Power_curr_full.interpolate(method='time').reindex(new_time_index)
方法2:用resample简化流程
直接用resample生成10秒间隔的空值框架,保留原始数据对应时间点的值,再插值填充:
import pandas as pd Power_curr = pd.read_csv("pathtodata.csv", parse_dates=['Timestamp']) Power_curr.set_index('Timestamp', inplace=True) # 按10秒重采样生成空值,再基于时间插值填充 Power_curr_interpolated = Power_curr.resample('10s').asfreq().interpolate(method='time')
这个方法更简洁,resample('10s').asfreq()会自动保留原始数据中对应时间点的值,其余位置为NaN,随后的interpolate(method='time')会基于时间间隔进行线性插值。
内容的提问来源于stack exchange,提问作者mechanicalman
相关产品推荐
相关产品推荐

