如何按DataFrame原有时间频率填充缺失日期及数据?
按原有时间频率补全DataFrame缺失数据的解决方案
我来帮你解决这个按原有时间频率补全DataFrame缺失数据的问题,结合你提供的参考数据,咱们一步步实现:
1. 数据预处理:转换为正确的格式
首先需要把你给出的表格数据转换成pandas DataFrame,并且将时间列设置为datetime类型的索引(因为原数据的结构是Depth为行、时间为列,所以需要先转置):
import pandas as pd # 构造你提供的参考数据 data = { '5/19/2022 18:51': [200.6, 200.6, 200.6, 200.7, 200.7, 200.8, 200.9, 200.9, 200.8, 200.8, 200.7, 200.6, 200.7, 200.8, 201.1], '5/19/2022 19:21': [200.6, 200.7, 200.6, 200.5, 200.6, 200.7, 200.9, 201, 200.9, 200.8, 200.7, 200.7, 200.8, 200.9, 201], '5/19/2022 19:51': [200.5, 200.6, 200.6, 200.7, 200.8, 200.8, 201, 201.1, 201.1, 201.1, 201.1, 200.9, 200.9, 201, 201.2], '5/19/2022 20:21': [200.7, 200.8, 200.9, 200.9, 200.9, 201, 201.1, 201.1, 201, 201, 200.9, 200.9, 200.9, 201.1, 201.3], '5/19/2022 20:51': [201.2, 201.3, 201.3, 201.2, 201.2, 201.1, 201, 201, 200.9, 200.9, 201, 201.1, 201.3, 201.5, 201.7], '5/19/2022 21:21': [201, 201.1, 201, 200.9, 200.9, 200.9, 201, 201.1, 200.9, 200.8, 200.8, 201, 201.2, 201.3, 201.4], '5/19/2022 21:51': [200.7, 200.8, 200.8, 200.8, 200.8, 200.7, 200.8, 200.9, 200.9, 201, 200.9, 200.9, 201, 201, 201.1], '5/25/2022 0:22': [171.7, 171.7, 171.6, 171.7, 172, 172.3, 172.5, 172.7, 172.8, 173, 173.1, 173.2, 173.3, 173.5, 173.7], '5/25/2022 0:52': [171.7, 171.9, 172.1, 172.2, 172.3, 172.4, 172.6, 172.7, 172.8, 172.9, 173, 173.1, 173.3, 173.3, 173.4], '5/25/2022 1:22': [171.4, 171.5, 171.5, 171.6, 171.8, 172, 172.2, 172.3, 172.3, 172.4, 172.6, 172.8, 173.1, 173.2, 173.3], '5/25/2022 1:52': [171, 171.2, 171.3, 171.3, 171.5, 171.6, 171.8, 172.1, 172.2, 172.2, 172.2, 172.3, 172.5, 172.8, 172.9], '5/25/2022 2:22': [170.7, 170.7, 170.7, 170.9, 171.1, 171.3, 171.6, 171.8, 171.9, 172.1, 172.2, 172.3, 172.4, 172.6, 172.8], '5/25/2022 2:52': [170.7, 170.9, 171, 171.1, 171.2, 171.4, 171.6, 171.7, 171.8, 171.8, 172, 172.1, 172.3, 172.5, 172.7] } depth_index = [600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614] # 创建DataFrame并转置,让时间成为索引 df = pd.DataFrame(data, index=depth_index).T # 将索引转换为datetime类型 df.index = pd.to_datetime(df.index, format='%m/%d/%Y %H:%M')
2. 识别连续时间块并生成对应频率的完整索引
核心思路是:先拆分出数据中连续的时间片段(比如5/19的时间段和5/25的时间段是两个独立块,中间的5/20-5/24是缺失段),然后对每个连续块使用自身的时间频率生成完整的时间序列,最后合并所有块的索引:
# 计算相邻时间点的间隔(转换为分钟) time_diffs = df.index.to_series().diff().dt.total_seconds() / 60 # 标记间隔发生变化的位置,用来拆分时间块 change_mask = time_diffs != time_diffs.shift(1) block_starts = df.index[change_mask].tolist() # 把第一个时间点加入起始列表 block_starts.insert(0, df.index[0]) # 生成每个连续块的完整时间索引 full_index = pd.DatetimeIndex([]) for i in range(len(block_starts) - 1): start_time = block_starts[i] end_time = block_starts[i+1] # 获取当前块的时间频率(取相邻间隔的有效值) current_freq = int(time_diffs.loc[end_time]) # 生成该块的完整时间序列 block_index = pd.date_range(start=start_time, end=end_time, freq=f'{current_freq}min') full_index = full_index.union(block_index) # 处理最后一个时间块 last_start = block_starts[-1] last_end = df.index[-1] last_freq = int(time_diffs.dropna().iloc[-1]) last_block_index = pd.date_range(start=last_start, end=last_end, freq=f'{last_freq}min') full_index = full_index.union(last_block_index)
这个方法能自动适配数据中不同的时间频率(比如部分段是30分钟,部分是10分钟),不会强制统一成每日频率。
3. 重新索引并填充缺失值
最后用生成的完整索引重新对齐原DataFrame,按需填充NaN或0:
# 重新索引,缺失值默认填充为NaN df_full = df.reindex(full_index) # 如果需要填充为0,替换成下面的代码: # df_full = df.reindex(full_index, fill_value=0)
这样处理后,原数据中缺失的时间点(比如5/19 22:21到5/25 0:22之间的所有30分钟间隔点)都会被补全,对应的值为你指定的NaN或0,同时完全保留了原数据的时间频率。
内容的提问来源于stack exchange,提问作者roudan
相关产品推荐
相关产品推荐

