numpy 给定一个包含两个时间戳的列表,如何检查一个数组的索引是否在这些日期时间范围内?

8cdiaqws  于 2023-10-19  发布在  其他
关注(0)|答案(2)|浏览(99)

我有一个两个元素的列表,类型为pd.Timestamp,例如:

intervals = [
    [pd.Timestamp('2023-01-01 02:00:00'), pd.Timestamp('2023-01-01 03:00:00')], 
    [pd.Timestamp('2023-01-01 05:00:00'), pd.Timestamp('2023-01-01 07:00:00')],
    [pd.Timestamp('2023-01-01 07:30:00'), pd.Timestamp('2023-01-01 08:00:00')],
]

我也有一个示例框架,例如:

data = {'value': [1, 2, 3, 4]}
index = [
    pd.Timestamp('2023-01-01 01:00:00'),
    pd.Timestamp('2023-01-01 02:00:00'), 
    pd.Timestamp('2023-01-01 03:00:00'),
    pd.Timestamp('2023-01-01 04:00:00'),
]
df = pd.DataFrame(data, index=index)

现在,我如何检查该索引的框架是在所有的日期时间间隔?换句话说,对于每个元素的索引的框架(行)检查该行是否包含在第一个间隔,或在第二个间隔,或在第三个间隔,等等,通过这样做:

for start, end in intervals:
    df.index >= start & df.index >= end

我的想法是:
1.为每个区间创建一个布尔掩码,检查索引的每个元素是否都在区间内

masks = [
   [False, True, True, False],
   [False, False, False, False],
   [False, False, False, False],
]

1.通过应用|(逻辑或)运算符

mask = [False, True, True, False]

我希望以矢量化的方式执行1和2,因此我希望尽可能使用numpy或pandas。我目前正在使用Python中的列表管理数据结构。哪一条路最快,哪一条路最优雅?

huwehgph

huwehgph1#

您可以使用IntervalIndexget_indexer_for来识别现有的匹配,然后使用all来聚合:

idx = pd.IntervalIndex.from_tuples(list(map(tuple, intervals)), closed='both')
# or
# idx = pd.IntervalIndex.from_arrays(*zip(*intervals), closed='both')

out = (idx.get_indexer_for(df.index) != -1).all()

输出:False
工作原理:

idx.get_indexer_for(df.index)
# array([-1,  0,  0, -1])

# check if values are found
idx.get_indexer_for(df.index) != -1
# array([False, True,  True, False])

# are all values found?
(idx.get_indexer_for(df.index) != -1).all()
# False

检查哪些元素在范围内:

which = idx.get_indexer_for(df.index) != -1

输出:array([False, True, True, False])

所有组合

如果需要比较所有组合,请使用numpy

i = df.index.to_numpy()[:,None]
idx = pd.IntervalIndex.from_arrays(*zip(*intervals), closed='both')

out = (i >= idx.left) & (i <= idx.right)

输出量:

array([[False, False, False, False],
       [ True, False, False, False],
       [ True, False, False, False],
       [False, False, False, False]])
dwthyt8l

dwthyt8l2#

替代方法:

# Function to check if a date is in any of the intervals
def in_intervals(date, intervals):
    return any(start <= date <= end for start, end in intervals)

# Apply the function to each row
df['within_intervals'] = df.index.to_series().apply(in_intervals, intervals=intervals)

print(df)


                       value  within_intervals
2023-01-01 01:00:00      1             False
2023-01-01 02:00:00      2              True
2023-01-01 03:00:00      3              True
2023-01-01 04:00:00      4             False

相关问题