如何在Pandas DataFrame中按日期匹配重排数据并填充缺失值?
Pandas按日期匹配重排数据并填充缺失值的解决方案
嘿,我来帮你搞定这个Pandas数据整理的需求!因为你是编程新手,我会把步骤拆得很细,代码也加了详细注释,你跟着一步步来就能得到想要的结果~
1. 先把原始数据转换成Pandas DataFrame
首先我们得把你提供的原始数据先构建成Pandas能处理的DataFrame,方便后续操作:
import pandas as pd # 定义原始数据的列名(对应每个日期-价格对) cols = [ 'A_price1_date', 'A_price1_val', 'A_price2_date', 'A_price2_val', 'B_price1_date', 'B_price1_val', 'B_price2_date', 'B_price2_val', 'C_price1_date', 'C_price1_val' ] # 你提供的原始数据行 data_rows = [ ['19-12-04', 0.0, '19-12-05', 1.7, '19-12-05', 2.6, '19-12-06', 3.2, '19-12-05', 0.1], ['19-12-03', 1.5, '19-12-04', 1.7, '19-12-04', 2.6, '19-12-05', 3.2, '19-12-04', 0.1], ['19-12-02', 1.5, '19-12-03', 1.7, '19-12-03', 2.6, '19-12-04', 3.1, '19-12-03', 0.1], ['19-12-01', 1.5, '19-12-02', 1.8, '19-12-02', 2.7, '19-12-03', 3.2, '19-12-02', 0.1], ['19-11-29', 1.5, '19-12-01', 1.7, '19-11-29', 2.6, '19-12-02', 3.2, '19-12-01', 0.1], ['19-11-28', 1.6, '19-11-29', 1.7, '19-11-28', 2.6, '19-11-29', 3.1, '19-11-29', 0.1], ['19-11-27', 1.6, '19-11-28', 1.7, '19-11-27', 2.6, '19-11-28', 3.2, '19-11-28', 0.1], ['19-11-26', 1.6, '19-11-27', 1.7, '19-11-26', 2.6, '19-11-27', 3.2, '19-11-27', 0.2], ['19-11-25', 1.5, '19-11-26', 1.7, '19-11-25', 2.6, '19-11-26', 3.2, '19-11-26', 0.2], ['19-11-24', 1.5, '19-11-25', 1.7, '19-11-22', 2.6, '19-11-25', 3.2, '19-11-25', 0.2], ['19-11-22', 1.5, '19-11-24', 1.7, '19-11-21', 2.6, '19-11-22', 3.1, '19-11-24', 0.2] ] # 创建原始DataFrame df = pd.DataFrame(data_rows, columns=cols)
2. 拆分每个价格系列为「日期索引」的Series
我们需要把每个国家的每个价格类型(比如A的price1)单独提取出来,让日期作为索引,这样后续就能自动按日期匹配了:
# 定义一个工具函数:把日期列和价格列转换成日期索引的Series def create_price_series(date_col_name, val_col_name): # 用日期作为索引,价格作为值 price_series = pd.Series( df[val_col_name].values, index=pd.to_datetime(df[date_col_name], format='%y-%m-%d') ) # 防止同一日期出现多个值,只保留第一个 price_series = price_series.groupby(price_series.index).first() return price_series # 为每个价格系列创建对应的Series a_price1 = create_price_series('A_price1_date', 'A_price1_val') a_price2 = create_price_series('A_price2_date', 'A_price2_val') b_price1 = create_price_series('B_price1_date', 'B_price1_val') b_price2 = create_price_series('B_price2_date', 'B_price2_val') c_price1 = create_price_series('C_price1_date', 'C_price1_val')
3. 合并所有系列并对齐日期
把上面创建的所有Series合并成一个DataFrame,Pandas会自动按日期索引对齐,没有对应数据的位置会显示NaN:
# 合并所有价格系列,自动按日期对齐 merged_df = pd.concat([a_price1, a_price2, b_price1, b_price2, c_price1], axis=1) # 给列命名(你说列名不重要,这里用你提供的原名,也可以简化成['A p1', 'A p2', ...]) merged_df.columns = [ 'A Country price1', 'A Country price2', 'B Country price1', 'B Country price2', 'C Country price1' ]
4. 补全所有日期并填充缺失值
现在我们要把所有缺失的日期(比如19-11-23)补全,然后把NaN替换成你想要的?,最后按日期降序排序:
# 生成从最早到最晚的所有日期(每天一个) all_dates = pd.date_range(start=merged_df.index.min(), end=merged_df.index.max(), freq='D') # 重新索引,加入所有日期 merged_df = merged_df.reindex(all_dates) # 把缺失值替换成"?" merged_df = merged_df.fillna('?') # 把日期格式转换成你想要的"yy-mm-dd",并移到第一列 merged_df['date'] = merged_df.index.strftime('%y-%m-%d') cols = ['date'] + merged_df.columns[:-1].tolist() merged_df = merged_df[cols] # 按日期降序排序,和你期望的结果顺序一致 merged_df = merged_df.sort_values('date', ascending=False).reset_index(drop=True)
最终结果
运行完上面的代码后,打印merged_df就能得到和你期望完全一致的结果啦!如果想要简化列名,只需要修改merged_df.columns的内容即可,比如改成['A price1', 'A price2', 'B price1', 'B price2', 'C price1']。
内容的提问来源于stack exchange,提问作者Mono Neu Elogy
相关产品推荐
相关产品推荐

