我有一些这样的数据:
df = pd.DataFrame ({'code': ['A', 'A','A' ,'B', 'B','B', 'C'],
'type' : ['a', 'a', 'b', 'c', 'c', 'c', 'd'],
'start': ['2017-1-1', '2018-5-5', '2017-5-21', '2017-6-6','2017-7-8','2017-8-9','2018-5-1'],
'end': ['2017-5-20', 'now', '2017-5-4', '2017-7-7','2017-8-8','now','now']})
╔═══╦══════╦══════╦═══════════╦═══════════╗
║ ║ code ║ type ║ start ║ end ║
╠═══╬══════╬══════╬═══════════╬═══════════╣
║ 0 ║ A ║ a ║ 2017-1-1 ║ 2017-5-20 ║
╠═══╬══════╬══════╬═══════════╬═══════════╣
║ 1 ║ A ║ a ║ 2018-5-5 ║ now ║
╠═══╬══════╬══════╬═══════════╬═══════════╣
║ 2 ║ A ║ b ║ 2017-5-21 ║ 2017-5-4 ║
╠═══╬══════╬══════╬═══════════╬═══════════╣
║ 3 ║ B ║ c ║ 2017-6-6 ║ 2017-7-7 ║
╠═══╬══════╬══════╬═══════════╬═══════════╣
║ 4 ║ B ║ c ║ 2017-7-8 ║ 2017-8-8 ║
╠═══╬══════╬══════╬═══════════╬═══════════╣
║ 5 ║ B ║ c ║ 2017-8-9 ║ now ║
╠═══╬══════╬══════╬═══════════╬═══════════╣
║ 6 ║ C ║ d ║ 2018-5-1 ║ now ║
╚═══╩══════╩══════╩═══════════╩═══════════╝
并且我想使用熊猫将其转换如下所示:
╔═══╦══════╦══════╦═══════════╦═══════════╗
║ ║ code ║ type ║ start ║ end ║
╠═══╬══════╬══════╬═══════════╬═══════════╣
║ 0 ║ A ║ a ║ 2017-1-1 ║ 2017-5-20 ║
╠═══╬══════╬══════╬═══════════╬═══════════╣
║ 1 ║ A ║ a ║ 2018-5-5 ║ now ║
╠═══╬══════╬══════╬═══════════╬═══════════╣
║ 2 ║ A ║ b ║ 2017-5-21 ║ 2017-5-4 ║
╠═══╬══════╬══════╬═══════════╬═══════════╣
║ 3 ║ B ║ c ║ 2017-6-6 ║ now ║
╠═══╬══════╬══════╬═══════════╬═══════════╣
║ 4 ║ C ║ d ║ 2018-5-1 ║ now ║
╚═══╩══════╩══════╩═══════════╩═══════════╝
数据需要合并在 code 和 type 字段中,这些字段的 date 值构成一个连续的日期范围(例如日期[ 2017-6-6],[2017-7-7],[2017-7-8],[2017-8-8],[2017-8-9],现在可以合并到[2017-6-6]改为 now )。
如果日期不连续,则不应将它们分组/合并,并且开始和结束均不得更改。 我该如何实现?
答案 0 :(得分:1)
尝试一下:
grp_helper = df.groupby(['code','type'])\
.apply(lambda x: (pd.to_datetime(x['start']) -
pd.to_datetime(x['end'], errors='coerce').shift(1)
!= pd.Timedelta(days=1)).cumsum()).values
df.groupby(['code','type',grp_helper])[['start','end']]\
.agg({'start':'min','end':'max'}).reset_index().drop('level_2', axis=1)
输出:
code type start end
0 A a 2017-1-1 2017-5-20
1 A a 2018-5-5 now
2 A b 2017-5-21 2017-5-4
3 B c 2017-6-6 now
4 C d 2018-5-1 now