You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Pandas将起止日期数据扩展为面板数据(附示例)

使用Pandas扩展员工任职时间数据的实现步骤

给定表1的员工任职数据(包含Person、Company、Begin date、End Date字段,日期格式为MM/YYYY),需要通过Pandas自动扩展为表2的格式,补全每个月份的任职状态,空档期标记为Unemployed。

原始数据(表1)

PersonCompanyBegin dateEnd Date
Mr. BunCompany A8/198410/1984
Company B1/19853/1985

预期结果(表2)

PersonYearCompany
Mr. Bun8/1984Company A
9/1984Company A
10/1984Company A
11/1984Unemployed
12/1984Unemployed
1/1985Company B
2/1985Company B
3/1985Company B

实现步骤

  • 填充Person列空值:原始数据中部分行Person字段为空,用ffill()方法向前填充,确保每行都对应正确的人员。
  • 转换日期格式:将Begin date和End Date转换为Pandas datetime类型,指定格式为%m/%Y,方便后续生成时间序列。
  • 生成单条记录的月份序列:对每行数据,生成从入职到离职的所有月份,存储为列表列。
  • 展开月份序列:将包含月份列表的列展开为单行对应单个月份的结构。
  • 生成完整时间范围基准:找出整个数据的最早开始日期和最晚结束日期,生成该区间内的所有月份,作为基准序列。
  • 匹配任职状态:将展开后的任职数据与基准序列合并,未匹配到公司的月份填充为Unemployed。
  • 调整输出格式:将日期转换回MM/YYYY格式,调整列顺序为Person、Year、Company,并处理Person列的重复显示(仅保留第一行姓名,后续行留空)。

完整代码示例

import pandas as pd

# 模拟原始数据(实际可通过pd.read_csv等方法读取)
df = pd.DataFrame({
    'Person': ['Mr. Bun', None],
    'Company': ['Company A', 'Company B'],
    'Begin date': ['8/1984', '1/1985'],
    'End Date': ['10/1984', '3/1985']
})

# 填充Person列空值
df['Person'] = df['Person'].ffill()

# 转换日期列为datetime类型
df['Begin date'] = pd.to_datetime(df['Begin date'], format='%m/%Y')
df['End Date'] = pd.to_datetime(df['End Date'], format='%m/%Y')

# 生成每行的月份序列(MS表示每月第一天)
def generate_month_series(row):
    return pd.date_range(start=row['Begin date'], end=row['End Date'], freq='MS')

df['Months'] = df.apply(generate_month_series, axis=1)

# 展开月份序列为单行单月
expanded_df = df.explode('Months').drop(columns=['Begin date', 'End Date'])

# 生成完整时间范围的基准月份序列
min_start = df['Begin date'].min()
max_end = df['End Date'].max()
all_months = pd.date_range(start=min_start, end=max_end, freq='MS')
all_months_df = pd.DataFrame({'Months': all_months, 'Person': df['Person'].iloc[0]})

# 合并数据并填充失业状态
result_df = pd.merge(all_months_df, expanded_df, on=['Person', 'Months'], how='left')
result_df['Company'] = result_df['Company'].fillna('Unemployed')

# 转换日期格式并调整列顺序
result_df['Year'] = result_df['Months'].dt.strftime('%m/%Y')
result_df = result_df[['Person', 'Year', 'Company']]

# 处理Person列的重复显示
result_df['Person'] = result_df['Person'].where(result_df['Person'].shift() != result_df['Person'], '')

# 打印结果
print(result_df)

内容的提问来源于stack exchange,提问作者SChatcha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 17:40:25