如何将含重复值的timestamp列设为Pandas DataFrame唯一索引?
问题描述
从MongoDB数据库获取时序数据并转换为Pandas DataFrame进行后续操作。数据库中每个通道的单个样本为独立文档,部分通道采样时间一致,部分不同。
文档示例
timestamp: 2024-01-05T08:16:30.848+00:00 metaData: deviceId: "123" channelName: "Channel1" _id: 659c23016ad87924ff552882 Channel1: 10345
查询代码
使用以下代码查询指定通道数据:
b = pd.DataFrame(list(timeCol.find( {'metaData.deviceId':'123','metaData.channelName':{'$in':['Channel1','Channel2','Channel3','Channel4','Channel5']}}, {'_id':0,'metaData':0} ).sort('timestamp')))
生成的DataFrame示例
timestamp Channel1 Channel2 Channel3 Channel4 Channel5 0 2024-01-05 20:27:31.340 0.0 NaN NaN NaN NaN 1 2024-01-05 20:27:31.382 1.0 NaN NaN NaN NaN 2 2024-01-05 20:27:31.400 NaN 2456.0 NaN NaN NaN 3 2024-01-05 20:27:31.400 NaN NaN 10.231 NaN NaN 4 2024-01-05 20:27:31.400 NaN NaN NaN 2.4 NaN
其中Channel2-5通常共享时间戳,Channel1采样频率更高。需要将timestamp设为索引,保留唯一时间戳并正确整合各列数据,且不想多次调用数据库,也无法修改数据库存储方式。
解决方案
无需多次查询数据库,直接对现有DataFrame执行分组聚合操作即可实现需求,具体步骤如下:
- 按timestamp分组,提取各列有效数据
由于同一时间戳下同一通道只会有一个非空值,使用first()或max()均可提取到有效数据:
# 按timestamp分组,取每列第一个非空值 merged_df = b.groupby('timestamp').first().reset_index() # 或使用max(),效果一致(NaN不影响数值列的最大值计算) # merged_df = b.groupby('timestamp').max().reset_index()
- 设置timestamp为索引
merged_df = merged_df.set_index('timestamp')
处理后结果示例
Channel1 Channel2 Channel3 Channel4 Channel5 timestamp 2024-01-05 20:27:31.340 0.0 NaN NaN NaN NaN 2024-01-05 20:27:31.382 1.0 NaN NaN NaN NaN 2024-01-05 20:27:31.400 NaN 2456.0 10.231 2.4 NaN
补充说明
- 若部分时间戳下同一通道存在多个非空值(数据异常),可根据需求选择
mean()(取均值)或自定义聚合函数处理。 - 该方法仅需一次数据库查询,效率远高于多次查询后合并的方案。
内容的提问来源于stack exchange,提问作者user2731076
相关产品推荐
相关产品推荐

