熊猫:Groupby,循环并添加一小时迭代与组内的条件
Posted
技术标签:
【中文标题】熊猫:Groupby,循环并添加一小时迭代与组内的条件【英文标题】:Pandas: Groupby, loop and add one hour iterate with conditions within group 【发布时间】:2020-10-30 15:53:44 【问题描述】:我有一个如下的df,每个人都有一些重复的日期记录,我希望对其余数据保持完全相同的顺序/顺序,但希望只为重复的日期记录添加一小时。
df = pd.DataFrame(
'name': ['Jim', 'Jim', 'Jim', 'Jim', 'Mike', 'Mike', 'Mike', 'Mike',
'Polo', 'Polo', 'Polo', 'Polo', 'Polo', 'Tom', 'Tom', 'Tom', 'Tom'],
'Item ID': [80, 68, 751, 'Started', 32, 126, 68, 'Started', 105, 68, 251, 76, 'Started', 82, 251, 23, "Started"],
'Date':["2018-02-15", "2018-02-14", "2015-08-17", "2015-08-17",
"2018-09-14", "2018-06-01", "2018-06-01", "2018-05-31",
"2017-06-01", "2017-06-01", "2014-12-01", "2014-11-23", "2013-08-11",
"2017-07-14", "2016-02-16", "2016-02-16", "2015-06-05"],
)
name Item ID Date
0 Jim 80 2018-02-15
1 Jim 68 2018-02-14
2 Jim 751 2015-08-17 # duplicate date for Jim, add one hour here
3 Jim Started 2015-08-17
4 Mike 32 2018-09-14
5 Mike 126 2018-06-01 # duplicate date for Mike, add one hour here
6 Mike 68 2018-06-01
7 Mike Started 2018-05-31
8 Polo 105 2017-06-01 # duplicate date for Polo, add one hour here
9 Polo 68 2017-06-01
10 Polo 251 2014-12-01
11 Polo 76 2014-11-23
12 Polo Started 2013-08-11
13 Tom 82 2017-07-14
14 Tom 251 2016-02-16 # duplicate date for Tom, add one hour here
15 Tom 23 2016-02-16
16 Tom Started 2015-06-05
我写了一些代码,但效果不佳且效率低下。如果有人有任何想法,请帮助,非常感谢。 我的预期结果:
name Item ID Date
0 Jim 80 2018-02-15
1 Jim 68 2018-02-14
2 Jim 751 2015-08-17 00:01:00 # added
3 Jim Started 2015-08-17
4 Mike 32 2018-09-14
5 Mike 126 2018-06-01 00:01:00 # added
6 Mike 68 2018-06-01
7 Mike Started 2018-05-31
8 Polo 105 2017-06-01 00:01:00 # added
9 Polo 68 2017-06-01
10 Polo 251 2014-12-01
11 Polo 76 2014-11-23
12 Polo Started 2013-08-11
13 Tom 82 2017-07-14
14 Tom 251 2016-02-16 00:01:00 # added
15 Tom 23 2016-02-16
16 Tom Started 2015-06-05
【问题讨论】:
【参考方案1】:我们可以通过iloc
颠倒顺序执行duplicated
,然后将小时添加到原始日期
df.Date=pd.to_datetime(df.Date)+pd.to_timedelta(df.iloc[::-1].duplicated(['name','Date']).astype(int),unit='hour')
df
name Item ID Date
0 Jim 80 2018-02-15 00:00:00
1 Jim 68 2018-02-14 00:00:00
2 Jim 751 2015-08-17 01:00:00
3 Jim Started 2015-08-17 00:00:00
4 Mike 32 2018-09-14 00:00:00
5 Mike 126 2018-06-01 01:00:00
6 Mike 68 2018-06-01 00:00:00
7 Mike Started 2018-05-31 00:00:00
8 Polo 105 2017-06-01 01:00:00
9 Polo 68 2017-06-01 00:00:00
10 Polo 251 2014-12-01 00:00:00
11 Polo 76 2014-11-23 00:00:00
12 Polo Started 2013-08-11 00:00:00
13 Tom 82 2017-07-14 00:00:00
14 Tom 251 2016-02-16 01:00:00
15 Tom 23 2016-02-16 00:00:00
16 Tom Started 2015-06-05 00:00:00
【讨论】:
谢谢@YOBEN_S,想知道你的 Pandas 版本是什么?它显示错误“ValueError: invalid timedelta unit hours provided” 但是我将它更改为 unit='h' 然后它就可以工作了,是不是我的 Pandas 版本(0.23.4)太旧了?因为我的软件被我们的管理员锁定并且无法升级 @XaviorL 我在 pd.__version__ '1.0.5' 下 @XaviorL ,最好升级你的熊猫,因为在 0.25 之后他们添加了更多工具,例如explode
嗨@YOBEN_S,您的代码运行良好,只是想知道您为什么要反向执行?如果不介意,能稍微解释一下吗?我单独运行您的代码以查看步入结果。这里的逻辑是什么?原谅我的无知。谢谢
@XaviorL 这里的逻辑是获取第一个重复标记为 True :-) 因为它默认通过掩码第一个为 False,但是您需要第一个重复添加 1 小时,我们只需要颠倒顺序实现它【参考方案2】:
df['Date'] = pd.to_datetime(df['Date'])
df.loc[df.duplicated(subset=['name','Date'], keep='last'), 'Date'] = df['Date'] + pd.DateOffset(hours=1)
输出
name Item ID Date
0 Jim 80 2018-02-15 00:00:00
1 Jim 68 2018-02-14 00:00:00
2 Jim 751 2015-08-17 01:00:00
3 Jim Started 2015-08-17 00:00:00
4 Mike 32 2018-09-14 00:00:00
5 Mike 126 2018-06-01 01:00:00
6 Mike 68 2018-06-01 00:00:00
7 Mike Started 2018-05-31 00:00:00
8 Polo 105 2017-06-01 01:00:00
9 Polo 68 2017-06-01 00:00:00
10 Polo 251 2014-12-01 00:00:00
11 Polo 76 2014-11-23 00:00:00
12 Polo Started 2013-08-11 00:00:00
13 Tom 82 2017-07-14 00:00:00
14 Tom 251 2016-02-16 01:00:00
15 Tom 23 2016-02-16 00:00:00
16 Tom Started 2015-06-05 00:00:00
【讨论】:
嗨@Chris,非常感谢您的回答。它运行良好,但 YOBEN 更快, @XaviorL 出于好奇,您是否使用 timeit 或其他方式计算了性能差异?有兴趣看看有什么不同。以上是关于熊猫:Groupby,循环并添加一小时迭代与组内的条件的主要内容,如果未能解决你的问题,请参考以下文章