我的初始dataframe看起来如下:
| ID|开始|结束|持续时间天数|
| - -----|- -----|- -----|- -----|
| 1| 2023-05-20 12:00:00.000| 2023-06-03 12:00:00.000|十四|
| 2| 2023-05-20 12:00:00.000| 2023-05-23 12:00:00.000| 3|
| 1| 2023-06-01 12:00:00.000| 2023-06-03 12:00:00.000| 2|
如何从这到一个像下面这样的数据框架?问题是,有相当低的行(数百万)。因此,性能非常重要。
| ID|年份|月|持续时间天数|
| - -----|- -----|- -----|- -----|
| 1| 2023年|五月|十一|
| 2| 2023年|五月|3|
| 1| 2023年|六月|5个|
**更新:**请注意,可能会有一个多月的休息时间。示例:2023-02-20(2月)和2023-12-18(12月)
3条答案
按热度按时间b5lpy0ml1#
@jezrael的方法是正确的,但对于大型DataFrame来说可能是不现实的,因为它需要按天/小时重复行(从而创建具有数千万或数亿行的中间体)。
相反,使用pandas的
Period
作为重复行的单元似乎更合理。简而言之,这将使用
repeat
在其边界处按周期中断行,并使用groupby.cumcount
递增周期,使用start_time
/end_time
获得边界,最后使用groupby.sum
添加每个周期的持续时间。我自愿添加了几个中间变量,以使代码更容易理解,但如果需要,可以将许多步骤合并为一个步骤,以避免创建太多的中间列。
输出:
groupby.sum
之前的中间体:泛化
对于一个更通用的方法,您可以使用任何时期(如果您有足够的资源):
period = 'Y'
的输出:period = 'M'
的输出:hk8txs482#
第一个想法是按天
End/Start
列的差异重复行,并按GroupBy.size
计算每个ID/Year/Month
的行数:为了获得更好的精度,可以使用小时而不是天:
csbfibhn3#
你可以
lreshape
你的DataFrame然后使用split_months
(* 稍微调整 *):输出: