用真假分开白天和黑夜

2024-09-27 00:17:52 发布

您现在位置:Python中文网/ 问答频道 /正文

我是python和数据培训的初学者。目前正在开发一个虚拟出租车票价计算器数据框架,但为了获得更好的结果,我想将白天和夜间分开,以计算更好的票价

我目前拥有的代码:

d['time'] = pd.to_datetime(d['start']).dt.strftime('%H:%M')

for time in d['time']:
    hourMin = time.split(":")
    hour = int(hourMin[0])
    mins = int(hourMin[1])
    if hour >= 6 and hour <= 20:
        if(hour == 18):
            if(mins > 0):
                dtime = '0'
            else:
                dtime = '1'
        else:
            dtime = '1'
    else:
        day_time = '0'
        
    dtime[:10]
    d['time'] = dtime
    
d.head()

当我运行此程序时,我收到此部件上的IndexError: list index out of range错误mins = int(hourMin[1])

我真的很感激我能得到的任何帮助,因为我已经为此奋斗了4-5个小时


Tags: 数据代码框架iftimeelse计算器int
2条回答

熊猫有一些很有前景的发声功能: pandas.DataFrame.between_timepandas.DatetimeIndex.indexer_between_time

不幸的是,between_time返回的是数据帧,而不是布尔序列。因此与.loc一起使用并不方便

indexer_between_time返回索引位置的整数数组。与.iloc一起工作,但这对我们来说非常不舒服

此外,它们都要求索引为DateTime类型

首先,一些示例数据:

df = pd.DataFrame(pd.date_range(start = "2020-11-19 00:00",
                  end = "2020-11-19 23:59",
                  periods = 15),
                  columns = ["start"])
                 start
0  2020-11-19 00:00:00
1  2020-11-19 01:42:47
2  2020-11-19 03:25:34
3  2020-11-19 05:08:21
4  2020-11-19 06:51:08
5  2020-11-19 08:33:55
6  2020-11-19 10:16:42
7  2020-11-19 11:59:30
8  2020-11-19 13:42:17
9  2020-11-19 15:25:04
10 2020-11-19 17:07:51
11 2020-11-19 18:50:38
12 2020-11-19 20:33:25
13 2020-11-19 22:16:12
14 2020-11-19 23:59:00

添加一个新列,如果一行是Daytime或不是,该列将显示为True/False

df["Daytime"] = False

将索引设置为开始,日期时间列:

df = df.set_index("start")
                    Daytime
start                      
2020-11-19 00:00:00   False
2020-11-19 01:42:47   False
2020-11-19 03:25:34   False
2020-11-19 05:08:21   False
2020-11-19 06:51:08   False
2020-11-19 08:33:55   False
2020-11-19 10:16:42   False
2020-11-19 11:59:30   False
2020-11-19 13:42:17   False
2020-11-19 15:25:04   False
2020-11-19 17:07:51   False
2020-11-19 18:50:38   False
2020-11-19 20:33:25   False
2020-11-19 22:16:12   False
2020-11-19 23:59:00   False

时间戳的边界是什么

DayStart = "06:30:00"
DayEnd = "18:00:00"

正在创建匹配行的整数数组。您还可以将include_startinclude_end设置为具有打开或关闭的间隔

DayTime = df.index.indexer_between_time(DayStart, DayEnd)

我们能得到什么回报?与索引位置匹配的整数列表

>>> array([ 4,  5,  6,  7,  8,  9, 10])

我们现在可以使用它将第0列设置为True

df.iloc[DayTime,0] = True
                   Daytime
start                     
2020-11-19 00:00:00  False
2020-11-19 01:42:47  False
2020-11-19 03:25:34  False
2020-11-19 05:08:21  False
2020-11-19 06:51:08   True
2020-11-19 08:33:55   True
2020-11-19 10:16:42   True
2020-11-19 11:59:30   True
2020-11-19 13:42:17   True
2020-11-19 15:25:04   True
2020-11-19 17:07:51   True
2020-11-19 18:50:38  False
2020-11-19 20:33:25  False
2020-11-19 22:16:12  False
2020-11-19 23:59:00  False

使用between_time函数返回与条件匹配的数据帧:

df_DayFilter = df.between_time(DayStart, DayEnd)
                   Daytime
start                     
2020-11-19 06:51:08   True
2020-11-19 08:33:55   True
2020-11-19 10:16:42   True
2020-11-19 11:59:30   True
2020-11-19 13:42:17   True
2020-11-19 15:25:04   True
2020-11-19 17:07:51   True

我也很想知道是否有更优雅的方法来使用between_time

我觉得你把事情弄得太复杂了。您可以将列的.timetime对象进行比较:

(
    (time(6) <= di.time) & (di.time <= time(18))
) | (
    (di.time >= time(19)) & (di.time < time(21))
)

因此,这将检查时间是否介于6:00和18:00(包括这两个时间段)之间,或者19:00(包括这两个时间段)和21:00(不包括这两个时间段)之间

这也将提高工作效率。例如:

>>> di
DatetimeIndex(['2015-04-24 02:00:00', '2015-11-26 23:00:00',
               '2016-01-18 00:00:00', '2016-06-27 22:00:00',
               '2016-08-12 17:00:00', '2016-10-21 11:00:00',
               '2016-11-07 11:00:00', '2016-12-09 23:00:00',
               '2017-02-20 01:00:00', '2017-06-17 18:00:00'],
              dtype='datetime64[ns]', freq=None)
>>> ((time(6) <= di.time) & (di.time <= time(18))) | ((di.time >= time(19)) & (di.time < time(21)))
array([False, False, False, False,  True,  True,  True, False, False,
        True])

您可以使用.astype(int)将其转换为int

>>> (((time(6) <= di.time) & (di.time <= time(18))) | ((di.time >= time(19)) & (di.time < time(21)))).astype(int)
array([0, 0, 0, 0, 1, 1, 1, 0, 0, 1])

相关问题 更多 >

    热门问题