逐组增长熊猫数据框

时间:2020-02-10 22:10:42

标签: pandas dataframe multi-index

我有一个多索引熊猫数据框。在我的示例中,有两个级别:车辆(具有属性A和B)和reference_days(具有属性1和2)。对于每辆车,每天都有一组时间(以字符串格式显示,例如,“ 2330”对应于11.30pm,“ 30”对应于0.30am)。这些时间按时间顺序排序,但对于1 reference_day,它们可能会跨越“午夜”行。即,可以将凌晨02.00的时间算作上一天。我想有一个新列,如果该行的时刻实际上对应于一个“新”日期(即是否已超过午夜线),则该列的值为1。此示例对应于火车时刻表,其中记录了前一天在午夜至(大约)凌晨4点之间的旅行。

示例:

dict = {"vehicle": ["A"]*8 + ["B"]*8,
        "reference_day" : [1, 1, 1, 1, 2, 2, 2, 2]*2,
        "time" : [1830, 2200, 30, 115, 1700, 1800, 2300, 100,
                  1900, 2300, 15, 200, 1500, 2000, 2330, 120]}
df = pd.DataFrame(dict).reset_index(drop=True).set_index(["vehicle", "reference_day"], drop=True)

DataFrame看起来像这样:

                       time
vehicle reference_day      
A       1              1830
        1              2200
        1                30
        1               115
        2              1700
        2              1800
        2              2300
        2               100
B       1              1900
        1              2300
        1                15
        1               200
        2              1500
        2              2000
        2              2330
        2               120

我想再有一个这样的专栏:

                       time   next_day
vehicle reference_day      
A       1              1830   0
        1              2200   0
        1                30   1
        1               115   1
        2              1700   0
        2              1800   0
        2              2300   0
        2               100   1
B       1              1900   0
        1              2300   0
        1                15   1
        1               200   1
        2              1500   0
        2              2000   0
        2              2330   0
        2               120   1

我应该如何优雅地实现这一目标?希望任何人都能提供帮助,谢谢!

3 个答案:

答案 0 :(得分:1)

让我们尝试一下:

df['next_day'] = df.groupby(level=[0,1])['time']\
                   .transform(lambda x: x.diff().lt(0).cumsum())

输出:

                       time  next_day
vehicle reference_day                
A       1              1830         0
        1              2200         0
        1                30         1
        1               115         1
        2              1700         0
        2              1800         0
        2              2300         0
        2               100         1
B       1              1900         0
        1              2300         0
        1                15         1
        1               200         1
        2              1500         0
        2              2000         0
        2              2330         0
        2               120         1

答案 1 :(得分:1)

我们还可以使用:

df['next_day']= (df.groupby(level = [0,1])[['time']].diff()
                   .lt(0)
                   .groupby(level = [0,1])['time']
                   .cumsum()
                   .astype(int)
                )
print(df)
                       time  next_day
vehicle reference_day                
A       1              1830         0
        1              2200         0
        1                30         1
        1               115         1
        2              1700         0
        2              1800         0
        2              2300         0
        2               100         1
B       1              1900         0
        1              2300         0
        1                15         1
        1               200         1
        2              1500         0
        2              2000         0
        2              2330         0
        2               120         1

请记住,这在性能级别上与groupby.transform类似,尽管在这里我们将applytransform分组两次,并且使用带有几种方法的lambda函数通常也很慢。

答案 2 :(得分:0)

以下内容可能有帮助?

df['next_day']=(df['time']<400).astype(int)