如何在groupby期间将日期字符串转换为agg函数中的日期时间
Posted
技术标签:
【中文标题】如何在groupby期间将日期字符串转换为agg函数中的日期时间【英文标题】:How to convert date string to datetime in agg function during groupby 【发布时间】:2020-02-12 18:26:59 【问题描述】:给定一个数据框,如何将Item
与Updated Date
的max
值分组(作为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