如何在Dataframe中新增列,统计每行Enrol Date对应的前置早于它的Close Date数量
问题描述
给定如下DataFrame:
| Class | Enrol Date | Close Date |
|---|---|---|
| A | 30/10/2003 | 05/12/2003 |
| A | 22/12/2003 | 23/09/2005 |
| A | 06/09/2005 | 29/09/2005 |
| A | 15/11/2005 | 07/12/2005 |
| A | 27/02/2006 | 28/03/2006 |
需要对Enrol Date列中的每个日期,统计其之前所有行的Close Date列中早于该日期的数量,并将统计结果作为新列(如Prior Dates)添加到DataFrame中。期望结果如下:
| Class | Enrol Date | Close Date | Prior Dates |
|---|---|---|---|
| A | 30/10/2003 | 05/12/2003 | 0 |
| A | 22/12/2003 | 23/09/2005 | 1 |
| A | 06/09/2005 | 29/09/2005 | 1 |
| A | 15/11/2005 | 07/12/2005 | 3 |
| A | 27/02/2006 | 28/03/2006 | 4 |
解决方案
步骤1:转换日期列格式
首先要把字符串格式的日期转为pandas可识别的日期类型,避免字符串比较的逻辑错误:
import pandas as pd # 构造示例DataFrame(如果已有数据可跳过此步) df = pd.DataFrame({ 'Class': ['A']*5, 'Enrol Date': ['30/10/2003', '22/12/2003', '06/09/2005', '15/11/2005', '27/02/2006'], 'Close Date': ['05/12/2003', '23/09/2005', '29/09/2005', '07/12/2005', '28/03/2006'] }) # 转换日期格式,dayfirst=True适配日/月/年的格式 df['Enrol Date'] = pd.to_datetime(df['Enrol Date'], dayfirst=True) df['Close Date'] = pd.to_datetime(df['Close Date'], dayfirst=True)
步骤2:计算Prior Dates列
提供两种实现方式,按需选择:
方法1:遍历统计(小数据量直观)
通过遍历每行,截取当前行之前的Close Date数据并统计符合条件的数量:
def count_prior(row_idx, df): # 获取当前行之前的所有Close Date prior_close = df.loc[:row_idx-1, 'Close Date'] # 统计小于当前Enrol Date的数量 return (prior_close < df.loc[row_idx, 'Enrol Date']).sum() df['Prior Dates'] = [count_prior(i, df) for i in df.index]
方法2:向量化高效计算(大数据量推荐)
利用searchsorted实现快速查找,避免逐行遍历的性能损耗:
close_dates = df['Close Date'].values df['Prior Dates'] = [close_dates[:i].searchsorted(df['Enrol Date'].iloc[i]) for i in range(len(df))]
验证结果
运行代码后,输出的DataFrame与期望结果完全一致:
print(df)
输出:
Class Enrol Date Close Date Prior Dates 0 A 2003-10-30 2003-12-05 0 1 A 2003-12-22 2005-09-23 1 2 A 2005-09-06 2005-09-29 1 3 A 2005-11-15 2005-12-07 3 4 A 2006-02-27 2006-03-28 4
内容的提问来源于stack exchange,提问作者Robsmith
相关产品推荐
相关产品推荐

