如何从pandas DataFrame行值生成日期列表并完成行拆分与收益分摊
Pandas 订单按停留日期拆分行并均摊收入实现方案
实现思路
- 第一步:日期类型标准化:先将
booking_check_in字段转换为pandas的datetime格式,避免后续日期计算出现格式报错 - 第二步:生成每日停留日期序列:对每行数据,以
booking_check_in为起始日期,days_of_stay为天数生成连续日期列表,存入新增的date_stayed字段 - 第三步:拆分多行:将
date_stayed字段的列表展开,一行拆分为多行,其余字段自动复制对应原始行的取值 - 第四步:收入均摊:将原始
booking_earned数值除以days_of_stay,得到每日对应分摊收入 - 第五步:字段规整:删除不需要的原始字段,重置索引即可得到目标结果
完整代码示例
import pandas as pd # 构造样例数据(如果是自己的数据集直接读取即可,不需要这段) data = { "booking_date": ["2019-09-14", "2019-10-21", "2020-01-01"], "booking_check_in": ["2019-12-20", "2019-11-01", "2020-03-02"], "days_of_stay": [2, 1, 2], "booking_currency": [1, 1, 1], "booking_earned": [611632.0, 742806.0, 1400000.0] } df = pd.DataFrame(data) # 1. 转换入住日期为datetime类型 df["booking_check_in"] = pd.to_datetime(df["booking_check_in"]) # 2. 生成停留日期列表 df["date_stayed"] = df.apply( lambda x: pd.date_range(start=x["booking_check_in"], periods=x["days_of_stay"], freq="D"), axis=1 ) # 3. 将date_stayed列表拆分为多行 df_exploded = df.explode("date_stayed", ignore_index=True) # 4. 均摊收入到每一天 df_exploded["booking_earned"] = df_exploded["booking_earned"] / df_exploded["days_of_stay"] # 5. 保留所需字段、重置索引得到最终结果 result = df_exploded[["booking_date", "date_stayed", "booking_currency", "booking_earned"]].reset_index(drop=True)
运行print(result)即可输出你需要的目标格式数据。
关键说明
pd.date_range是pandas内置的日期序列生成方法,freq="D"代表日期间隔为1天,periods参数指定生成的日期数量,刚好匹配停留天数explode是pandas 0.25及以上版本支持的方法,可直接将列中的列表/序列元素拆分为独立行,其余列自动继承原行值,是实现一行拆多行的最高效方案- 如果你使用的pandas版本低于0.25,可使用以下代码替代explode功能:
df = df.join(pd.DataFrame(df['date_stayed'].tolist(), index=df.index).stack().reset_index(level=1, drop=True).rename('date_stayed'))
内容的提问来源于stack exchange,提问作者Stefan Subagia
相关产品推荐
相关产品推荐

