我有一个多索引熊猫数据框。在我的示例中,有两个级别:车辆(具有属性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
我应该如何优雅地实现这一目标?希望任何人都能提供帮助,谢谢!
答案 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
类似,尽管在这里我们将apply
或transform
分组两次,并且使用带有几种方法的lambda函数通常也很慢。
答案 2 :(得分:0)
以下内容可能有帮助?
df['next_day']=(df['time']<400).astype(int)