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