我有一个数据结构,我正在使用pandas,我正在获取计划的最小数据。所以数据结构如下所示
Engagement ID Plan Start Date
A 17-7-2017
A 18-7-2017
A 20-7-2017
我正在努力实现这个目标
Engagement ID Plan Start Date Earliest Plan start date
A 17-7-2017 17-7-2017
A 18-7-2017 17-7-2017
A 20-7-2017 17-7-2017
我能够像这样做
engagement_df_earliest_plan_date = engagement_df.loc[engagement_df.groupby('Engagement Id', sort=False)['Plan Start Date'].idxmin()]
engagement_df_earliest_plan_date = engagement_df_earliest_plan_date[['Engagement Id','Plan Start Date']];
engagement_df_earliest_plan_date = engagement_df_earliest_plan_date.rename(columns={'Plan Start Date': 'Earliest Plan Start Date'});
但我觉得这不够优雅,并且想知道有更好的办法吗?
答案 0 :(得分:1)
让我们使用稍大一点的样本 -
df
Engagement ID Plan Start Date
0 A 17-7-2017
1 A 18-7-2017
2 A 20-7-2017
3 B 21-7-2017
4 B 22-7-2017
5 C 29-7-2017
6 C 30-7-2017
如果需要,请使用pd.to_datetime
-
df['Plan Start Date'] = pd.to_datetime(df['Plan Start Date'], errors='coerce')
现在,要获得所需的输出,groupby
第一列,transform
相对于每个组中的first
行 -
df['Earliest Plan Start Date'] = \
df.groupby("Engagement ID")['Plan Start Date'].transform('first')
df
Engagement ID Plan Start Date Earliest Plan Start Date
0 A 2017-07-17 2017-07-17
1 A 2017-07-18 2017-07-17
2 A 2017-07-20 2017-07-17
3 B 2017-07-21 2017-07-21
4 B 2017-07-22 2017-07-21
5 C 2017-07-29 2017-07-29
6 C 2017-07-30 2017-07-29
然而,这可能并不理想,因为第一个日期可能并不总是最小的日期。为此,您可以使用nsmallest
+ map
-
v = df.groupby("Engagement ID", group_keys=False)['Plan Start Date'].nsmallest(1)
v.index = v.index.droplevel(1)
df['Earliest Plan Start Date'] = df['Engagement ID'].map(v)
或者,
df['Earliest Plan Start Date'] = df['Engagement ID'].replace(v)
df
Engagement ID Plan Start Date Earliest Plan Start Date
0 A 2017-07-17 2017-07-17
1 A 2017-07-18 2017-07-17
2 A 2017-07-20 2017-07-17
3 B 2017-07-21 2017-07-21
4 B 2017-07-22 2017-07-21
5 C 2017-07-29 2017-07-29
6 C 2017-07-30 2017-07-29
现在,您保证最早的日期。请注意,v
看起来像这样 -
v
Engagement ID
A 2017-07-17
B 2017-07-21
C 2017-07-29
Name: Plan Start Date, dtype: datetime64[ns]