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

Posted

技术标签:

【中文标题】如何在groupby期间将日期字符串转换为agg函数中的日期时间【英文标题】:How to convert date string to datetime in agg function during groupby 【发布时间】:2020-02-12 18:26:59 【问题描述】:

给定一个数据框,如何将ItemUpdated Datemax 值分组(作为datetime 而不是日期字符串)同时在结果数据框中保持日期字符串格式? p>

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

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

【问题讨论】:

【参考方案1】:

使用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

【讨论】:

感谢@rafaelc,认为我们必须在最后删除'date' 列:g.drop(columns=['date'], inplace=True) rafaelc 你能帮我解决这个问题吗***.com/questions/65252632/…【参考方案2】:

转换为日期时间并使用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

【讨论】:

【参考方案3】:

你可以像下面这样使用 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

【讨论】:

如问题中所述,我想将日期字符串保留在结果数据框中

以上是关于如何在groupby期间将日期字符串转换为agg函数中的日期时间的主要内容,如果未能解决你的问题,请参考以下文章

如何将日期字符串转换为 mysql 日期格式以使用 mysql 查询计算日期差异

Spark 2 将 scala 数组转换为 WrappedArray

在where子句期间将十进制转换为日期[重复]

Pandas groupby(),agg() - 如何在没有多索引的情况下返回结果?

sqlserver中如何把数字转换成时间的格式?

Pandas groupby agg - 如何获得计数?