基于日期列表为DataFrame地点新增不存在日期行,不复制非必要列
问题描述
现有一个包含lon、lat、datetime、others四列的Pandas DataFrame,其中datetime和others列部分行值为NaN。已生成对应每个(lon, lat)地点的日期子列表,子列表元素数量≥该地点现有日期数。需求是为每个地点的新增日期添加行,但不复制others这类非必要列。
示例代码与初始数据
# 创建初始DataFrame d = {'lon': [100, 100, 120], 'lat': [50, 50, 60]} df = pd.DataFrame(data=d) df = pd.concat([df, pd.DataFrame(columns=['datetime', 'others'])]) df.loc[0, 'datetime'] = '2000-09-09' df.loc[1, 'datetime'] = '1999-09-09' df.loc[0, 'others'] = 'notes1' df.loc[1, 'others'] = 'notes2' # 每个地点对应的目标日期列表(子列表元素数≥该地点现有日期数) datetimes = [['2023-05-17', '2023-05-02', '2023-04-28', '2000-09-09', '1999-09-09'], ['2023-06-01'], ]
初始DataFrame:
lon lat datetime others 0 100.0 50.0 2000-09-09 notes1 1 100.0 50.0 1999-09-09 notes2 2 120.0 60.0 NaN NaN
期望结果
lon lat datetime others 0 100.0 50.0 2023-05-17 NaN 1 100.0 50.0 2023-05-02 NaN 2 100.0 50.0 2023-04-28 NaN 3 100.0 50.0 2000-09-09 notes1 4 100.0 50.0 1999-09-09 notes2 5 120.0 60.0 2023-06-01 NaN
解决方案
直接用explode会复制所有列,不符合需求,换个思路:先生成包含所有目标日期的基础数据,再和原数据合并保留原有others值。
import pandas as pd # (初始DataFrame和datetimes列表代码同上,这里省略) # 1. 提取所有唯一的(lon, lat)地点 locations = df[['lon', 'lat']].drop_duplicates().reset_index(drop=True) # 2. 为每个地点绑定对应的日期列表,展开成全量日期行(此时只有地点和日期列) locations['datetime'] = datetimes full_dates_df = locations.explode('datetime', ignore_index=True) # 3. 左合并原DataFrame的有效(地点+日期+others)数据,新增日期自动补NaN result_df = full_dates_df.merge( df[['lon', 'lat', 'datetime', 'others']], on=['lon', 'lat', 'datetime'], how='left' ) # 输出结果 print(result_df)
步骤说明
- 第一步先拿到所有不重复的地点,避免重复处理同一个位置。
- 第二步给每个地点绑定对应的日期列表,用
explode展开成每行一个日期,这时候只有lon、lat、datetime三列,不会带others。 - 第三步用左合并,把原DataFrame中已经存在的(地点+日期)对应的
others值匹配过来,新增的日期因为原数据里没有,others自然就是NaN,完美符合要求。
内容的提问来源于stack exchange,提问作者zxdawn
相关产品推荐
相关产品推荐

