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

如何在Python中为每个ID填充日期区间内的行,并完善会员数据标记以实现月度会员统计图表绘制?

嘿,我来帮你搞定这个会员统计的问题!你需要把两个数据集关联起来,给Dataframe A添加上会员类型、活跃状态和终止标记,完全不用写低效的循环,用各个工具的内置功能就能高效实现。下面分Python(Pandas)、Excel、SQL三种场景给你具体方案:

Python(Pandas)解决方案

首先确保你的日期列是datetime类型(这是日期匹配的前提),然后通过合并+条件筛选关联两个DataFrame,最后生成所需列:

import pandas as pd

# 示例数据(你可以替换成自己的数据集)
df_a = pd.DataFrame({
    'ID': [123,123,123,123,456,456],
    'Date': ['2001-03-01','2001-04-01','2001-05-01','2001-06-01','2001-05-01','2001-06-01'],
    'Created Date': ['2001-03-01','2001-03-01','2001-03-01','2001-03-01','2001-05-01','2001-05-01']
})

df_b = pd.DataFrame({
    'ID': [123,123,456],
    'Start Date': ['2001-03-01','2001-05-01','2001-05-01'],
    'End Date': ['2001-04-30','2001-06-01','2001-06-30'],
    'Membership': ['Bronze','Iron','Gold']
})

# 1. 转换所有日期列为datetime类型
df_a['Date'] = pd.to_datetime(df_a['Date'])
df_a['Created Date'] = pd.to_datetime(df_a['Created Date'])
df_b['Start Date'] = pd.to_datetime(df_b['Start Date'])
df_b['End Date'] = pd.to_datetime(df_b['End Date'])

# 2. 按ID合并两个DataFrame,筛选出Date在会员有效期内的行
merged = pd.merge(df_a, df_b, on='ID', how='left')
filtered = merged[(merged['Date'] >= merged['Start Date']) & (merged['Date'] <= merged['End Date'])]

# 3. 添加所需列
filtered['Active'] = 1  # 有效期内标记为活跃
# 当Date等于会员结束日期时标记终止,否则为空
filtered['Termination'] = filtered.apply(lambda x: 1 if x['Date'] == x['End Date'] else '', axis=1)

# 4. 整理成期望的列格式(注:你的期望输出中Join Date与示例Created Date有差异,这里按Created Date处理)
result = filtered.rename(columns={
    'Created Date': 'Join Date',
    'End Date': 'Leave Date'
})[['ID', 'Date', 'Join Date', 'Leave Date', 'Active', 'Termination', 'Membership']]

print(result)

如果需要取每个ID的最早加入日期作为Join Date、最晚结束日期作为Leave Date,可以在最后一步用groupby.transform来统一处理:

# 覆盖Join Date为每个ID的最早Created Date
result['Join Date'] = result.groupby('ID')['Join Date'].transform('min')
# 覆盖Leave Date为每个ID的最晚End Date
result['Leave Date'] = result.groupby('ID')['Leave Date'].transform('max')
Excel解决方案

方法1:Power Query(推荐,适合大数据量)

  1. 把两个表格导入Power Query(数据>自表格/区域)
  2. 在Power Query中,选择Dataframe A,点击合并查询,按ID关联Dataframe B
  3. 添加自定义列,输入公式判断日期是否在有效期内:=if [Date] >= [Start Date] and [Date] <= [End Date] then true else false
  4. 筛选自定义列为true的行,然后添加列:
    • Active:=1
    • Termination:=if [Date] = [End Date] then 1 else null
  5. 重命名列并加载回Excel

方法2:公式法(适合小数据量)

假设Dataframe A在Sheet1,Dataframe B在Sheet2:

  • 会员类型列(E2):=XLOOKUP(1, (Sheet1!$A2=Sheet2!$A:$A)*(Sheet1!$B2>=Sheet2!$B:$B)*(Sheet1!$B2<=Sheet2!$C:$C), Sheet2!$D:$D, "")
  • Active列(F2):=IF(E2<>"",1,"")
  • Termination列(G2):=IF(Sheet1!$B2=XLOOKUP(1, (Sheet1!$A2=Sheet2!$A:$A)*(Sheet1!$B2>=Sheet2!$B:$B)*(Sheet1!$B2<=Sheet2!$C:$C), Sheet2!$C:$C),1,"")
    然后下拉填充公式即可。
SQL解决方案

通过JOIN关联两个表,用WHERE筛选日期范围,CASE语句生成终止标记:

SELECT 
    a.ID,
    a.Date,
    a.`Created Date` AS `Join Date`,
    b.`End Date` AS `Leave Date`,
    1 AS Active,
    CASE WHEN a.Date = b.`End Date` THEN 1 ELSE NULL END AS Termination,
    b.Membership
FROM DataframeA a
INNER JOIN DataframeB b 
    ON a.ID = b.ID
    AND a.Date BETWEEN b.`Start Date` AND b.`End Date`
ORDER BY a.ID, a.Date;

如果需要统一每个ID的Join/Leave Date,可以用窗口函数:

SELECT 
    ID,
    Date,
    MIN(`Created Date`) OVER (PARTITION BY ID) AS `Join Date`,
    MAX(`End Date`) OVER (PARTITION BY ID) AS `Leave Date`,
    Active,
    Termination,
    Membership
FROM (
    SELECT 
        a.ID,
        a.Date,
        a.`Created Date`,
        b.`End Date`,
        1 AS Active,
        CASE WHEN a.Date = b.`End Date` THEN 1 ELSE NULL END AS Termination,
        b.Membership
    FROM DataframeA a
    INNER JOIN DataframeB b 
        ON a.ID = b.ID
        AND a.Date BETWEEN b.`Start Date` AND b.`End Date`
) t
ORDER BY ID, Date;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 09:57:50