从具有时区日期格式的 python 数据框中提取给定两个日期的子集

Extract a subset given two dates from a python dataframe with timezone date format

我有以下数据框:

|      ID             |     date                       |
|---------------------|--------------------------------|
|          1          |     2022-02-03 22:01:12+01:00  |
|          2          |     2022-02-04 21:11:21+01:00  |
|          3          |     2022-02-05 11:11:21+01:00  |
|          4          |     2022-02-07 23:01:12+01:00  |
|          5          |     2022-02-07 14:31:14+02:00  |
|          6          |     2022-02-08 18:12:01+02:00  |
|          7          |     2022-02-09 20:21:02+02:00  |
|          8          |     2022-02-11 15:41:25+02:00  |
|          9          |     2022-02-15 11:21:27+02:00  |

我创建了一个函数,给定两个具有以下格式的日期 (YYYYY-MM-DD HH:MM:SS),获取该时间间隔之间的数据子集。代码如下:

# Selects a subset of the dataset from a given time interval
def select_interval(df, start_date, end_date):
    # Confirm the given format and convert to datetime
    start_date = pd.to_datetime(start_date, format='%Y-%m-%d %H:%M:%S')
    end_date = pd.to_datetime(end_date, format='%Y-%m-%d %H:%M:%S')
    # Create a copy of the original df
    subset = df.copy()
    # Creates a temporary column to store the values related to the specific date
    subset['tmp_date'] = subset['date'].apply(lambda a: pd.to_datetime(str(a.date()) + " " + str(a.time())))
    if start_date < end_date:
        mask = (subset['tmp_date'] >= start_date) & (subset['tmp_date'] <= end_date)
        df = df.loc[mask]
    
    return df

我需要根据日期和时间构造附加列,因为如果我直接将参数传递的日期与日期列(包含时区)的值进行比较,则会出现以下错误:TypeError:无法比较原始偏移和偏移感知日期时间

我想知道是否有办法以更优化的方式解决这个问题,因为我认为创建 tmp_date 列会使我的函数效率降低。感谢您的帮助。

在将参数传递给函数之前,您可以将 start_date & end_date 更改为时区感知。

import pytz
start_date = pytz.utc.localize(start_date)
end_date = pytz.utc.localize(end_date)

pd.to_datetimeutc=True

您可以将可选参数 utc=True 传递给 pd.to_datetime 函数,以便将 timezone-aware 输入转换为 UTC。然后您应该能够将日期列与 start_dateend_date 进行比较,以便对 df

进行子集化

这是一步一步的例子,

print(df)

   ID                       date
0   1  2022-02-03 22:01:12+01:00
1   2  2022-02-04 21:11:21+01:00
2   3  2022-02-05 11:11:21+01:00
3   4  2022-02-07 23:01:12+01:00
4   5  2022-02-07 14:31:14+02:00
5   6  2022-02-08 18:12:01+02:00
6   7  2022-02-09 20:21:02+02:00
7   8  2022-02-11 15:41:25+02:00
8   9  2022-02-15 11:21:27+02:00

# Convert to UTC
df['date'] = pd.to_datetime(df['date'], utc=True)
print(df)

   ID                      date
0   1 2022-02-03 21:01:12+00:00
1   2 2022-02-04 20:11:21+00:00
2   3 2022-02-05 10:11:21+00:00
3   4 2022-02-07 22:01:12+00:00
4   5 2022-02-07 12:31:14+00:00
5   6 2022-02-08 16:12:01+00:00
6   7 2022-02-09 18:21:02+00:00
7   8 2022-02-11 13:41:25+00:00
8   9 2022-02-15 09:21:27+00:00

# Filter the rows with boolean indexing
subset = df[df['date'].between('2022-02-03 21:01:12', '2022-02-07 22:01:11')]
print(subset)

   ID                      date
0   1 2022-02-03 21:01:12+00:00
1   2 2022-02-04 20:11:21+00:00
2   3 2022-02-05 10:11:21+00:00
4   5 2022-02-07 12:31:14+00:00