含重复日期索引的DataFrame使用combine_first合并及新增位置问题
解决气象数据DataFrame合并:覆盖旧数据并保留新增位置
你的问题核心是需要基于时间+位置的唯一标识来合并数据,既要用新数据覆盖旧数据,还要保留新数据里的新增位置。之前用cumcount的方式因为依赖原df的索引结构,导致新增位置丢失,这里给你一个更可靠的方案:
解决方案代码
import pandas as pd import numpy as np # 初始化原始数据 df = pd.DataFrame(np.random.randint(0,30,size=(10, 4)), columns=(['Temp', 'Precip', 'Wind', 'Pressure'])) df['Location'] =[2,2,3,3,4,4,5,5,6,6] df.index = pd.to_datetime(["2020-05-18 12:00:00","2020-05-19 12:00:00","2020-05-18 12:00:00","2020-05-19 12:00:00","2020-05-18 12:00:00","2020-05-19 12:00:00","2020-05-18 12:00:00","2020-05-19 12:00:00","2020-05-18 12:00:00","2020-05-19 12:00:00"]) # 初始化含新增位置1的df1 df1 = pd.DataFrame(np.random.randint(0,30,size=(11, 4)), columns=(['Temp', 'Precip', 'Wind', 'Pressure'])) df1['Location'] =[1,2,2,3,3,4,4,5,5,6,6] df1.index = pd.to_datetime(["2020-05-19 12:00:00", "2020-05-20 12:00:00", "2020-05-19 12:00:00", "2020-05-20 12:00:00", "2020-05-19 12:00:00", "2020-05-20 12:00:00", "2020-05-19 12:00:00", "2020-05-20 12:00:00", "2020-05-19 12:00:00", "2020-05-20 12:00:00", "2020-05-19 12:00:00"]) # 关键步骤:将时间+Location设置为复合索引,确保每条记录的唯一标识 df = df.set_index(['Location'], append=True) df1 = df1.set_index(['Location'], append=True) # 合并并保留最新数据:先放旧数据df,再放新数据df1,groupby后取最后一条(即新数据覆盖旧数据) df3 = pd.concat([df, df1]).groupby(level=[1,0]).last() # 整理索引顺序并重置 df3 = df3.sort_index(level=[0,1]).reset_index(level=0) print(df3)
方案解释
- 设置复合索引:把
Location和原时间索引组合成复合索引,这样每条数据的唯一标识是(时间, Location),完美匹配你的业务场景——每个位置在不同时间的气象数据是唯一的。 - 合并并覆盖:用
pd.concat把旧数据放在前面,新数据放在后面,然后按复合索引分组,取last()就能自动让新数据覆盖同一(时间, Location)下的旧数据。 - 索引整理:最后按位置和时间排序,重置索引得到整洁的结果,同时自动保留了df1里新增的位置1。
原方法丢失位置1的原因
你之前用cumcount生成的附加索引是基于原df的时间分组计数,而df里根本没有位置1的记录,combine_first的逻辑是以左边的df索引为基准,填充缺失值,所以不会主动新增df里没有的索引项,导致位置1的数据被丢弃。而用(时间+Location)的复合索引,能完整保留两个df的所有索引项,再通过分组取最新值实现覆盖,完全解决了这个问题。
内容的提问来源于stack exchange,提问作者Pad
相关产品推荐
相关产品推荐

