基于时间戳匹配替换DataFrame值:Python水位时间序列填充问题
问题
本人是Python新手,现有一组时间戳非连续的水位时间序列数据,希望生成连续时间序列,无数据区间赋值为NaN。已创建包含NaN的连续时间序列DataFrame,但通过循环调用df.replace函数填充观测值后,结果仍为全NaN序列。
输入数据示例
Time stamp Level 2020-06-18 18:00:00 161.287 2020-06-18 21:00:00 161.286 2020-06-19 12:00:00 161.283 2020-06-19 15:00:00 161.283
现有代码
dti = pd.date_range("2020-05-01", periods=1224, freq="3H") dti_df = pd.DataFrame(dti, columns=['Timestamp']) dti_df["Level"] = np.nan dti_df df3 = pd.read_csv(r'C:\Users\krusm\Documents\water Levels Resampled.csv') for i in dti_df.index: for j in df3.index: if dti_df['Timestamp'][i] == df3['Timestamp'][j]: dti_df['Level'][i].replace(df3['Level'][j], inplace = True) else: pass dti_df
当前输出(全NaN)
Time stamp Level 2020-06-18 18:00:00 NaN 2020-06-18 21:00:00 NaN 2020-06-19 00:00:00 NaN 2020-06-18 03:00:00 NaN 2020-06-19 06:00:00 NaN 2020-06-19 09:00:00 NaN 2020-06-19 12:00:00 NaN 2020-06-19 15:00:00 NaN
期望输出
Time stamp Level 2020-06-18 18:00:00 161.287 2020-06-18 21:00:00 161.286 2020-06-19 00:00:00 NaN 2020-06-18 03:00:00 NaN 2020-06-19 06:00:00 NaN 2020-06-19 09:00:00 NaN 2020-06-19 12:00:00 161.283 2020-06-19 15:00:00 161.283
解决方法
问题根源
replace用法错误:你调用的是单个元素的replace方法,它用于替换元素内的特定值,而非直接赋值。比如dti_df['Level'][i]是NaN值,replace(df3['Level'][j], inplace=True)无法将NaN替换为目标值(因未指定to_replace参数),完全不生效。- 时间戳类型不匹配:从CSV读取的
df3['Timestamp']默认是字符串类型,而dti_df['Timestamp']是datetime64类型,直接用==比较永远不匹配,导致循环内的条件从未触发。
方法一:修正循环逻辑(不推荐,效率低)
先转换时间戳类型,再直接赋值替代replace:
import pandas as pd import numpy as np # 创建连续时间序列 dti = pd.date_range("2020-05-01", periods=1224, freq="3H") dti_df = pd.DataFrame(dti, columns=['Timestamp']) dti_df["Level"] = np.nan # 读取数据并转换时间戳为datetime类型 df3 = pd.read_csv(r'C:\Users\krusm\Documents\water Levels Resampled.csv') df3['Timestamp'] = pd.to_datetime(df3['Timestamp']) # 循环匹配赋值 for i in dti_df.index: current_ts = dti_df['Timestamp'][i] match_row = df3[df3['Timestamp'] == current_ts] if not match_row.empty: dti_df.loc[i, 'Level'] = match_row['Level'].values[0]
方法二:用Pandas内置方法(推荐,高效简洁)
利用merge或reindex实现时间序列对齐,无需手动循环:
方式A:使用merge
import pandas as pd import numpy as np # 创建连续时间序列 dti = pd.date_range("2020-05-01", periods=1224, freq="3H") dti_df = pd.DataFrame(dti, columns=['Timestamp']) # 读取数据并转换时间戳类型 df3 = pd.read_csv(r'C:\Users\krusm\Documents\water Levels Resampled.csv') df3['Timestamp'] = pd.to_datetime(df3['Timestamp']) # 左合并自动填充匹配值,不匹配的留NaN result = pd.merge(dti_df, df3, on='Timestamp', how='left')
方式B:使用reindex
将时间列设为索引后重新对齐,代码更简洁:
import pandas as pd import numpy as np # 创建连续时间序列 dti = pd.date_range("2020-05-01", periods=1224, freq="3H") # 读取数据,转换时间戳并设为索引 df3 = pd.read_csv(r'C:\Users\krusm\Documents\water Levels Resampled.csv') df3['Timestamp'] = pd.to_datetime(df3['Timestamp']) df3 = df3.set_index('Timestamp') # 重新索引到连续时间,自动填充NaN result = df3.reindex(dti) # 可选:将索引转回列 result = result.reset_index().rename(columns={'index': 'Timestamp'})
关键提示
- 优先选择方法二,Pandas内置方法的效率远高于手动循环,尤其适合大数据量场景。
- 无论哪种方法,必须确保两个DataFrame的时间戳类型一致(均为
datetime64),否则匹配会失败。
内容的提问来源于stack exchange,提问作者Rahat Usman
相关产品推荐
相关产品推荐

