如何在groupby期间在agg函数中将日期字符串转换为datetime

时间:2019-10-16 03:39:13

标签: python pandas dataframe datetime pandas-groupby

给出一个数据框,如何将Item的值max分组为Updated Date(作为datetime而不是日期字符串)同时保持日期字符串格式为结果数据框

df = pd.DataFrame([['A', 10, 'Jun 12, 2019 06:16 PM'],
                  ['A', 20, 'Jul 26, 2019 10:56 AM'],
                  ['B', 30, 'May 20, 2019 05:54 PM'],
                  ['B', 40, 'Apr 28, 2019 06:42 PM']],
                  columns=['Item', 'Quantity', 'Updated Date'])
>>> df
  Item  Quantity           Updated Date
0    A        10  Jun 12, 2019 06:16 PM
1    A        20  Jul 26, 2019 10:56 AM
2    B        30  May 20, 2019 05:54 PM
3    B        40  Apr 28, 2019 06:42 PM

预期产量

  Item  Quantity           Updated Date
0    A        30  Jul 26, 2019 10:56 AM
1    B        70  May 20, 2019 05:54 PM

我尝试过的事情

如果我将'Updated Date': max放在agg()中,它将简单地按字母顺序返回最大值

>>> df.groupby(['Item'], as_index=False).agg({'Quantity': sum, 'Updated Date': max})
  Item  Quantity           Updated Date
0    A        30  Jun 12, 2019 06:16 PM   # expected to be Jul 26
1    B        70  May 20, 2019 05:54 PM

如果我应用pd.to_datetime(),它会给我带来更接近的结果,但日期字符串格式会失真

df['Updated Date'] = pd.to_datetime(df['Updated Date'])
df.groupby(['Item'], as_index=False).agg({'Quantity': sum, 'Updated Date': max})
  Item  Quantity        Updated Date
0    A        30 2019-07-26 10:56:00
1    B        70 2019-05-20 17:54:00

是否可以仅在pd.to_datetime()期间应用groupby?这里的挑战是日期时间格式不能保证为'%b%d,%Y%I:%M%p',而我想保留结果中的日期字符串。

3 个答案:

答案 0 :(得分:2)

使用datetime作为比较的参考。

g = (df.assign(date=pd.to_datetime(df['Updated Date']))
    .groupby('Item')
    .agg({'Quantity': 'sum', 'date': 'idxmax'}))

g['Updated Date'] = df.loc[g.date, 'Updated Date'].tolist()

      Quantity           Updated Date
Item                                 
A           30  Jul 26, 2019 10:56 AM
B           70  May 20, 2019 05:54 PM

答案 1 :(得分:1)

转换为日期时间并使用idxmax是可行的方法。您无需更改数据框,例如:

# these are the index of the max dates
s = pd.to_datetime(df['Updated Date']).groupby(df['Item']).idxmax()

(df.groupby('Item')[['Quantity']].sum()        # get the sum of quantity
   .merge(df.loc[s, ['Item','Updated Date']],  # merge with the original rows for dates
          on='Item'                            # on the Item of course
          )
)

输出:

  Item  Quantity           Updated Date
0    A        30  Jul 26, 2019 10:56 AM
1    B        70  May 20, 2019 05:54 PM

答案 2 :(得分:0)

您可以使用如下所示的lambda来实现

df = pd.DataFrame([['A', 10, 'Jun 12, 2019 06:16 PM'],
                  ['A', 20, 'Jul 26, 2019 10:56 AM'],
                  ['B', 30, 'May 20, 2019 05:54 PM'],
                  ['B', 40, 'Apr 28, 2019 06:42 PM']],
                  columns=['Item', 'Quantity', 'Updated Date'])

df.groupby(['Item'], as_index=False).agg({'Quantity': sum, 'Updated Date': lambda g: g.loc[pd.to_datetime(df["Updated Date"]).idxmax()]})

或不使用诸如

的应用功能
df["Updated Date 2"] = pd.to_datetime(df["Updated Date"])
result = df.groupby(['Item'], as_index=False).agg({'Quantity': sum, 'Updated Date 2': "idxmax"})
result["Updated Date"] = df["Updated Date"].loc[result["Updated Date 2"]].values
result.drop(columns="Updated Date 2", inplace=True)
result