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

基于列值的Pandas Shift报错求解决:同产品日期重叠判定

问题描述

我有一个包含以下5列的Pandas DataFrame:

Product_ID, Start_Date, End_Date, Turnover, cumcount

其中Product_ID不唯一,cumcount用于记录同产品的出现次数(范围为0-5),数据已按Product_ID和Start_Date排序。由于同Product_ID的Start_Date可能存在重叠,我仅想保留与首个记录日期不重叠的条目。

我写的代码片段如下:

df= df.sort_values(by=[ "Product_ID", "Start_Date"])

check1 = df["Product_ID"] == df["Product_ID"].shift(1)

conditions = [check1 & ( df["End_Date"].shift(df["cumcount"]) > df["Start_Date"]),
check1 & ( df["End_Date"].shift(df["cumcount"]) < df["Start_Date"]),
~check1 ]

choices = [0, 1, 1]

df["result"] = np.select(conditions, choices)

设计思路是根据cumcount的值偏移对应行数,判断当前记录是否在首个记录的日期范围内,但执行时报错:

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

希望在不硬编码偏移量的前提下解决该问题。

样本数据

{'Product_ID': {0: 'CJ48HL',
  1: 'CL23P3',
  2: 'CL5WKS',
  3: 'DA0AAM',
  4: 'DA0AAM'},
 'Start_Date': {0: Timestamp('2022-02-11 00:00:00'),
  1: Timestamp('2022-11-11 00:00:00'),
  2: Timestamp('2022-10-24 00:00:00'),
  3: Timestamp('2022-04-01 00:00:00'),
  4: Timestamp('2022-04-06 00:00:00')},
 'Turnover': {0: 1143845.0,
  1: 512476.0,
  2: 178382.0,
  3: 2104083.0,
  4: 1300434.0},
 'count': {0: 0, 1: 0, 2: 0, 3: 0, 4: 1},
 'End_Date': {0: Timestamp('2022-02-25 00:00:00'),
  1: Timestamp('2022-11-25 00:00:00'),
  2: Timestamp('2022-11-07 00:00:00'),
  3: Timestamp('2022-04-15 00:00:00'),
  4: Timestamp('2022-04-20 00:00:00')}}

期望输出

Product_ID  Start_Date Turnover    count  End_Date   result
0     CJ48HL   2022-02-11  1143845.0    0   2022-02-25    1
1     CL23P3   2022-02-11   512476.0    0   2022-11-07    1
2     CL5WKS   2022-10-24   178382.0    0   2022-11-07    1
3     DA0AAM   2022-04-01  2104083.0    0   2022-04-15    1
4     DA0AAM   2022-04-06  1300434.0    1   2022-04-20    0
5     DA0AAM   2022-04-10  1451521.0    2   2022-04-24    0
6     DA0AAM   2022-04-20  2501520.0    3   2022-05-04    1
解决方案

错误原因

df["End_Date"].shift(df["cumcount"])写法有误:shift()方法仅接受单个整数作为偏移量,无法处理Series类型的动态偏移值,这导致后续布尔判断出现歧义,触发报错。

正确实现思路

要判断每条记录是否和同产品的首个记录日期不重叠,核心是先获取每个Product_ID对应的首个记录的End_Date,再用当前记录的Start_Date与该值直接比较:

  1. 按Product_ID分组,提取每组的首个End_Date并广播到组内所有行
  2. 新组的首个记录直接标记为保留;同组其他记录,若Start_Date大于组内首个End_Date则标记为保留,否则标记为不保留

代码实现

import pandas as pd
import numpy as np

# 确保数据按Product_ID和Start_Date排序(若未预先排序)
df = df.sort_values(by=["Product_ID", "Start_Date"])

# 为每个Product_ID获取首个记录的End_Date,并广播到组内所有行
df['first_end_date'] = df.groupby('Product_ID')['End_Date'].transform('first')

# 生成result列
df['result'] = np.where(
    df['cumcount'] == 0,  # 组内首个记录直接标记为1
    1,
    np.where(df['Start_Date'] > df['first_end_date'], 1, 0)  # 非首个记录根据日期重叠判断
)

# 可选:删除辅助列
df = df.drop('first_end_date', axis=1)

验证结果

用样本数据测试后,会得到符合期望的输出:

  • 每个产品的首个记录result为1
  • DA0AAM的第4、5条记录Start_Date小于首个记录的End_Date(2022-04-15),result为0
  • DA0AAM的第6条记录Start_Date(2022-04-20)大于首个记录的End_Date,result为1

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 14:30:57