重新索引Pandas DataFrame时数据丢失,如何扩展日期保留原数据?
问题描述
想要扩展DataFrame的日期范围以练习插值,要求保留原数据,仅扩展日期范围,其余值为NaN,但使用reindex后所有数据都变成了NaN。
原代码:
import pandas as pd df = pd.DataFrame({'value': [0,1,2], 'date':[pd.to_datetime('2017-04-01'), pd.to_datetime('2020-04-01'), pd.to_datetime('2022-04-01')]}) df = df.set_index('date')['value'] # 正确的df输出应为: # date # 2017-04-01 0 # 2020-04-01 1 # 2022-04-01 2 # Name: value, dtype: int64
尝试扩展的代码:
date = pd.date_range(start='2015-03-01', end='2050-01-01', freq='M') full_data = df.reindex(date).fillna(0)
结果所有数据变为NaN,期望保留原数据,其余为NaN。
错误原因
你的原数据索引是每月第一天(如2017-04-01),但pd.date_range(freq='M')生成的是每月最后一天(如2017-04-30),两者日期完全不匹配,reindex找不到对应的值,所以全部变成NaN。另外你提前用了fillna(0),这会把所有缺失值(包括原本应该保留的位置)都填充为0,不符合需求。
解决方案
有两种方法可以解决:
方法1:生成每月第一天的日期范围(和原索引对齐)
使用freq='MS'(Month Start,每月第一天)生成日期范围,和原数据索引匹配:
import pandas as pd df = pd.DataFrame({'value': [0,1,2], 'date':[pd.to_datetime('2017-04-01'), pd.to_datetime('2020-04-01'), pd.to_datetime('2022-04-01')]}) df = df.set_index('date')['value'] # 生成每月第一天的日期范围 date_range = pd.date_range(start='2015-03-01', end='2050-01-01', freq='MS') full_data = df.reindex(date_range) # 查看结果:原数据位置保留值,其余为NaN print(full_data.loc['2017-04-01']) # 输出0.0
方法2:将原数据索引调整为每月最后一天
如果需要保留freq='M'(每月最后一天)的日期范围,可把原数据索引转换为当月最后一天:
import pandas as pd df = pd.DataFrame({'value': [0,1,2], 'date':[pd.to_datetime('2017-04-01'), pd.to_datetime('2020-04-01'), pd.to_datetime('2022-04-01')]}) # 将日期转换为当月最后一天 df['date'] = df['date'] + pd.offsets.MonthEnd(0) df = df.set_index('date')['value'] # 生成每月最后一天的日期范围 date_range = pd.date_range(start='2015-03-01', end='2050-01-01', freq='M') full_data = df.reindex(date_range) print(full_data.loc['2017-04-30']) # 输出0.0,保留原数据
注意:不要提前用fillna(0),保留NaN以便后续练习插值操作。
内容的提问来源于stack exchange,提问作者Lostsoul
相关产品推荐
相关产品推荐

