【问题标题】:Pandas how to filter DataFrame on time period熊猫如何按时间段过滤DataFrame
【发布时间】:2018-08-16 18:56:50
【问题描述】:

我有一个包含下表的文件:

    Name        AvailableDate            totalRemaining
0   X3321       2018-03-14 13:00:00      200
1   X3321       2018-03-14 14:00:00      200
2   X3321       2018-03-14 15:00:00      200
3   X3321       2018-03-14 16:00:00      200
4   X3321       2018-03-14 17:00:00      193

我想返回一个包含特定时间期间所有记录的DataFrame,而不管实际的日期如何。

我按照这里的例子:

filter pandas dataframe by time

但是当我执行以下操作时:

## setup
import pandas as pd
import numpy as np

### Step 2
### Check available slots
file2 = r'C:\Users\user\Desktop\Files\data.xlsx'

slots = pd.read_excel(file2,na_values='')

## filter the preferred ones
slots['nextAvailableDate'] = pd.to_datetime((slots['nextAvailableDate']))


slots['times'] = pd.to_datetime((slots['nextAvailableDate']))
slots = slots[slots['times'].between('21:00:00', '02:00:00')]

这将返回空 DataFrame 以及此解决方案:

slots = slots[slots['times'].dt.strftime('%H:%M:%S').between('21:00:00', '02:00:00')]

有没有办法在不单独创建时间列的情况下正确地做到这一点?请问我应该如何解决这个问题?

我的目标:

Name        AvailableDate            totalRemaining
0   X3321       2018-03-14 21:00:00      200
1   X3321       2018-03-14 22:00:00      200
2   X3321       2018-03-14 23:00:00      200
3   X3321       2018-03-14 00:00:00      200
4   X3321       2018-03-14 01:00:00      193

数据集中出现的每一天。

【问题讨论】:

    标签: python python-3.x pandas datetime python-datetime


    【解决方案1】:

    我认为需要between_timeDatetimeindex 一起使用由set_index 创建的列,添加reset_indexreindex 以获得相同的列顺序:

    print (slots)
         Name        AvailableDate  totalRemaining
    0   X3321  2018-03-14 21:00:00             200
    1   X3321  2018-03-14 20:00:00             200
    2   X3321  2018-03-14 22:00:00             200
    3   X3321  2018-03-14 23:00:00             200
    4   X3321  2018-03-14 00:00:00             200
    5   X3321  2018-03-14 01:00:00             193
    6   X3321  2018-03-14 13:00:00             200
    7   X3321  2018-03-14 14:00:00             200
    8   X3321  2018-03-14 15:00:00             200
    9   X3321  2018-03-14 16:00:00             200
    10  X3321  2018-03-14 17:00:00             193
    
    slots['AvailableDate'] = pd.to_datetime(slots['AvailableDate'])
    
    df = (slots.set_index('AvailableDate')
              .between_time('21:00:00', '02:00:00')
              .reset_index()
              .reindex(columns=df.columns))
    print (df)
            AvailableDate   Name  totalRemaining
    0 2018-03-14 21:00:00  X3321             200
    1 2018-03-14 22:00:00  X3321             200
    2 2018-03-14 23:00:00  X3321             200
    3 2018-03-14 00:00:00  X3321             200
    4 2018-03-14 01:00:00  X3321             193
    

    【讨论】:

    • 效果很好,谢谢。 NameError: name 'df' is not defined 出现了,因为我没有将正确的 DF 传递给 columns=df.columns。现在一切都好。
    【解决方案2】:

    您可以将pd.Series.betweendatetime 对象一起使用,如下所示。

    from datetime import datetime
    
    start = datetime.strptime('21:00:00', '%H:%M:%S').time()
    end = datetime.strptime('02:00:00', '%H:%M:%S').time()
    
    slots = slots[slots['times'].dt.time.between(start, end)]
    

    使用示例

    from datetime import datetime
    import pandas as pd
    
    slots = pd.DataFrame({'times': ['2018-03-08 05:00:00', '2018-03-08 07:00:00',
                                    '2018-03-08 01:00:00', '2018-03-08 20:00:00',
                                    '2018-03-08 22:00:00', '2018-03-08 23:00:00']})
    
    
    slots['times'] = pd.to_datetime(slots['times'])
    
    start = datetime.strptime('21:00:00', '%H:%M:%S').time()
    end = datetime.strptime('23:30:00', '%H:%M:%S').time()
    
    slots = slots[slots['times'].dt.time.between(start, end)]
    
    #                 times
    # 4 2018-03-08 22:00:00
    # 5 2018-03-08 23:00:00
    

    【讨论】:

    • 很遗憾我不能奖励这两个答案,您的 strptime 在我正在从事的项目的后期非常有用。谢谢
    猜你喜欢
    • 1970-01-01
    • 2016-05-05
    • 2015-07-02
    • 1970-01-01
    • 1970-01-01
    • 2022-08-17
    • 2018-08-09
    • 2020-01-13
    相关资源
    最近更新 更多