【问题标题】:Check that any of three columns is within a column date range检查三列中的任何一列是否在列日期范围内
【发布时间】:2018-11-30 00:11:50
【问题描述】:

我有一个包含三个日期时间列的 DataFrame:


tp.loc[:, ['Arrival1', 'Arrival2', 'Departure']].head()

        Arrival1            Arrival2           Departure
0 2018-11-26 05:45:00 2018-11-26 12:00:00 2018-1-26 08:00:00
1 2018-11-26 22:00:00 2018-11-27 00:00:00 2018-11-26 23:00:00
2 2018-11-26 05:45:00 2018-11-26 08:15:00 2018-11-26 06:45:00
3 2018-11-26 07:30:00 2018-11-26 10:15:00 2018-11-26 08:30:00
4 2018-12-02 07:30:00 2018-12-02 21:30:00 2018-12-02 08:00:00

我只想获取到达 1、到达 2 或出发(三者中的任何一个)在以下列范围(任何行)内的 tp 行:

db.loc[db['country'] == 'AT']

country        banStartDate          banEndDate
102      AT 2018-12-01 14:00:00 2018-12-01 22:59:00
161      AT 2018-12-01 23:00:00 2018-12-02 21:00:00
51       AT 2018-12-07 23:00:00 2018-12-08 22:59:00

在本例中,我只想从 tp 中检索第 4 行,因为 Arrival2 在 db 的日期范围内。

有没有简单的方法?

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    使用pd.read_csv() 读入数据框后,您可以使用pd.concat() 和布尔掩码和列表解析,然后是drop_duplicates()

    from io import StringIO
    import pandas as pd
    
    df1 = StringIO('''
                Arrival1            Arrival2           Departure
    0  2018-11-26 05:45:00  2018-11-26 12:00:00  2018-1-26 08:00:00
    1  2018-11-26 22:00:00  2018-11-27 00:00:00  2018-11-26 23:00:00
    2  2018-11-26 05:45:00  2018-11-26 08:15:00  2018-11-26 06:45:00
    3  2018-11-26 07:30:00  2018-11-26 10:15:00  2018-11-26 08:30:00
    4  2018-12-02 07:30:00  2018-12-02 21:30:00  2018-12-02 08:00:00
    ''')
    
    df2 = StringIO('''
        country        banStartDate          banEndDate
    102      AT  2018-12-01 14:00:00  2018-12-01 22:59:00
    161      AT  2018-12-01 23:00:00  2018-12-02 21:00:00
    51       AT  2018-12-07 23:00:00  2018-12-08 22:59:00
    ''')
    
    tp = pd.read_csv(df1, sep=r'\s{2,}', engine='python', parse_dates=[0,1,2])
    db = pd.read_csv(df2, sep=r'\s{2,}', engine='python', parse_dates=[1,2]).reset_index()
    
    pd.concat([tp.loc[((tp>db.loc[i,'banStartDate']) & (tp<db.loc[i,'banEndDate'])).any(axis=1)] for i in range(db.shape[0])]).drop_duplicates()
    

    返回:

                 Arrival1            Arrival2           Departure
    4 2018-12-02 07:30:00 2018-12-02 21:30:00 2018-12-02 08:00:00
    

    【讨论】:

      【解决方案2】:

      您可以使用pandas.DataFrame.any 和axis = 'row'(或1)来查找日期在开始和结束之间的位置。无论数据库的“国家”列有多少,您都需要其中的 3 个或一个 for 循环。

      另外,我相信(我可能是错的)您需要将这些字符串转换为 python datetime 变量。代码看起来与此类似;

      tp[(datetime.strptime(Start_Date, '%Y-%d-%m %H:%M:%S')> tp >datetime.strptime(End_Date, '%Y-%d-%m %H:%M:%S')).any(axis=1)]
      

      【讨论】:

        猜你喜欢
        • 2019-07-07
        • 1970-01-01
        • 2021-01-10
        • 1970-01-01
        • 2021-06-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-28
        相关资源
        最近更新 更多