Python 按特定顺序将多个函数应用于GroupBy对象

Python 按特定顺序将多个函数应用于GroupBy对象,python,pandas,pandas-groupby,Python,Pandas,Pandas Groupby,我有一个数据框df,其中at列date包含日期 如果我想计算每个组中日期之间的最大差异,这是否可行(无需重新分组,也无需使用.apply)?如果我这样做 df 身份证日期| ---+------- 1 | 2020-01-20 1 | 2020-01-25 2 | 2020-02-03 2 | 2020-02-04 每个id的最大差异=df.groupby(“id”).diff(1.max() 每个id的最大差异 身份证件 -- 1 5 这当然会给我想要的所有组之间的最大差异 id

我有一个数据框
df
,其中at列
date
包含日期

如果我想计算每个组中日期之间的最大差异,这是否可行(无需重新分组,也无需使用
.apply
)?如果我这样做


df
身份证日期|
---+-------
1  | 2020-01-20
1  | 2020-01-25
2  | 2020-02-03
2  | 2020-02-04
每个id的最大差异=df.groupby(“id”).diff(1.max()
每个id的最大差异
身份证件
--
1  5
这当然会给我想要的所有组之间的最大差异

id
--
1  5
2  1
我知道我可以为每个id重新分组
max\u diff\u,但我认为

max_diff_for_each_id=df.groupby(“id”).diff(1.groupby(“id”).max()
不是真的“漂亮”,如果你有多个功能要应用,那么必须一直重新分组会带来大量的开销

这是否可行(无需重新分组,也无需使用.apply)

我认为通常不会,如果每个组只有2个值或其他一些数据模式,那么应该有替代方案

#if always 2 values per id in order
df1 = df.groupby("id")['date'].agg(['min','max'])
max_diff_for_each_id = df1['max'].sub(df1['min']).dt.days
或:

一个想法是将
id
转换为索引,但是
max(level=0)
只是隐藏
.groupby(level=0).max()
,所以这应该是一个技巧解决方案(在我看来)


可能存在多个
groupby
,如:

max_diff_for_each_id = df.groupby("id")['date'].diff(1).groupby(df["id"]).max().dt.days
或创建自定义函数,如:

max_diff_for_each_id = df.groupby("id")['date'].apply(lambda x: x.diff().max()).dt.days

max_diff_for_each_id = df.groupby("id")['date'].agg(lambda x: x.diff().max()).dt.days

IIUC,你可以做:

groups = df.groupby('id')
result = groups['date'].max() - groups['date'].min()
print(result)
输出

id
1   5 days
2   1 days
Name: date, dtype: timedelta64[ns]
id
1   5 days
2   1 days
dtype: timedelta64[ns]
替代版本:

frame = df.groupby('id').agg({'date': ['max', 'min']})
result = frame[('date', 'max')] - frame[('date', 'min')]
print(result)
输出

id
1   5 days
2   1 days
Name: date, dtype: timedelta64[ns]
id
1   5 days
2   1 days
dtype: timedelta64[ns]

单向使用
numpy.ptp

df.groupby("id").apply(np.ptp)
输出:

id
1   5 days
2   1 days
dtype: timedelta64[ns]
id
1   5 days
2   7 days
dtype: timedelta64[ns]
每个组可以使用任意数量的值

# print(df)
   id       date
0   1 2020-01-20
1   1 2020-01-25
2   1 2020-01-21
3   2 2020-02-03
4   2 2020-02-04
5   2 2020-02-06
6   2 2020-02-10

df.groupby("id").apply(np.ptp)
输出:

id
1   5 days
2   1 days
dtype: timedelta64[ns]
id
1   5 days
2   7 days
dtype: timedelta64[ns]

我真的希望避免使用
.apply
.agg
(编辑问题)一个组可以有两个以上的日期吗?如果使用矢量化函数,为什么不使用agg?当然可以,yop。超级。我对这个例子不满意(My
date
范围从1个日期到大约100个日期,取决于组)-这只是为了举例说明,因为在示例中需要
id 1 5天2 4天名称:date,数据类型:timedelta64[ns]
@jezrael您是对的。最大差异和ptp不一样,我不再确定ptp是否是正确的方法。让我们等待OP的回归;)没错,这个解决方案和@Dani Mesejo答案一样,只是更简单而已。