Python 使用dataframe分组函数计算日期差
我有这样一个数据帧:Python 使用dataframe分组函数计算日期差,python,pandas,Python,Pandas,我有这样一个数据帧: id_a | date 12 | 2020-01-01 12 | 2020-01-02 13 | 2020-01-01 13 | 2020-01-03 14 | 2020-01-01 14 | 2020-01-02 14 | 2020-01-06 我希望能够根据id_a来区分每个组的最大日期和最小日期 得到 id_a | date | diff 12 | 2020-01-01 | 1 12 | 2020-01-02 |
id_a | date
12 | 2020-01-01
12 | 2020-01-02
13 | 2020-01-01
13 | 2020-01-03
14 | 2020-01-01
14 | 2020-01-02
14 | 2020-01-06
我希望能够根据id_a来区分每个组的最大日期和最小日期
得到
id_a | date | diff
12 | 2020-01-01 | 1
12 | 2020-01-02 | 1
13 | 2020-01-01 | 2
13 | 2020-01-03 | 2
14 | 2020-01-01 | 5
14 | 2020-01-02 | 5
14 | 2020-01-06 | 5
我正试着这样做:
df['diff'] = df.groupby('id_a').apply(lambda x: max(x['date']) - min(x['date']))
但我有点挣扎
我在正确的道路上吗?您想要的是
转换
而不是应用
。同样np.ptp
也可以:
# convert to datetime, ignore if already is
df['date'] = pd.to_datetime(df['date'])
df['date_diff'] = df.groupby('id_a')['date'].transform(np.ptp)
输出:
id_a date date_diff
0 12 2020-01-01 1 days
1 12 2020-01-02 1 days
2 13 2020-01-01 2 days
3 13 2020-01-03 2 days
4 14 2020-01-01 5 days
5 14 2020-01-02 5 days
6 14 2020-01-06 5 days
更新:如果要从
日期a
获取最大值
,从日期b
获取最小值
:
groups = df.groupby('id_a')
min_dates = groups['date_b'].transform('min')
max_dates = groups['date_a'].transform('max')
df['date_diff'] = max_dates - min_dates
我们可以使用
groupby
,然后使用map
和np.timedelta
来获得以天为单位的数值差异
s = df.groupby(["id_a"]).agg(min_date=("date", "min"), max_date=("date", "max"))
df['day_diff'] = df["id_a"].map((s["max_date"] - s["min_date"]) / np.timedelta64(1, "D"))
你可以试试加入。但它可能需要您创建额外的数据帧
df_min = df.groupby('id_a', as_index=False).agg({'date':'min'})
df_max = df.groupby('id_a', as_index=False).agg({'date':'max'})
df2 = pd.merge(df,df_max,on=["id_a"],how="inner")
df2 = pd.merge(df2,df_min,on=["id_a"],how="inner")
df2.columns = ['id_a','date','max_date','min_date']
df2['diff'] = df2['max_date'] - df2['min_date']
df2.head()
id_a date max_date min_date diff
0 12 2020-01-01 2020-01-02 2020-01-01 1 days
1 12 2020-01-02 2020-01-02 2020-01-01 1 days
2 13 2020-01-01 2020-01-03 2020-01-01 2 days
3 13 2020-01-03 2020-01-03 2020-01-01 2 days
4 14 2020-01-01 2020-01-06 2020-01-01 5 days
为了能够回答这个问题,我们需要将日期转换为日期格式,但是这些日期的格式无效,它们是哪一年?哪一个值是日,哪一个值是月?@Erfan格式是YYYY-MM-dd您的方法是有效的,唯一的问题是您不想聚合行,而是要保持数据帧的相同形状,这就是为什么我们需要
transform
而不是apply
:df.groupby('id_a')['date'].transform(lambda x:x.max()-x.min())
Weird,这是您使用的numpy
版本,我尝试了相同的操作,结果是:DatetimeIndex无法执行操作ptp
@Erfan numpy'1.16.4',pandas'1.0.1'。还有,为什么有DatetimeIndex
?@quanghoanghanks很多,如果我需要使用两个不同的列呢?从日期a开始的最大日期和从日期b开始的最小日期?通过转换是否可能?
df_min = df.groupby('id_a', as_index=False).agg({'date':'min'})
df_max = df.groupby('id_a', as_index=False).agg({'date':'max'})
df2 = pd.merge(df,df_max,on=["id_a"],how="inner")
df2 = pd.merge(df2,df_min,on=["id_a"],how="inner")
df2.columns = ['id_a','date','max_date','min_date']
df2['diff'] = df2['max_date'] - df2['min_date']
df2.head()
id_a date max_date min_date diff
0 12 2020-01-01 2020-01-02 2020-01-01 1 days
1 12 2020-01-02 2020-01-02 2020-01-01 1 days
2 13 2020-01-01 2020-01-03 2020-01-01 2 days
3 13 2020-01-03 2020-01-03 2020-01-01 2 days
4 14 2020-01-01 2020-01-06 2020-01-01 5 days