You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Pandas高效判断DataFrame行的区间包含关系?

Pandas风格的区间包含判断方法

Hey there! As a fellow Pandas enthusiast, I totally get wanting to ditch those clunky nested loops—Pandas is built for vectorized operations, which are way faster and more idiomatic. Let's walk through a few better ways to solve your problem of finding rows in df2 that fit within any interval from df1.

First, let's set up your sample data so we can test the solutions:

import pandas as pd
import numpy as np

df1 = pd.DataFrame({
    'start': [1, 2],
    'value': ['TEST', 'TEST'],
    'end': [5, 3]
})

df2 = pd.DataFrame({
    'start': [2, 3],
    'value': ['TEST2', 'TEST2'],
    'end': [10, 4]
})

1. 推荐:Numpy广播的完全向量化方法

This is the most efficient approach, especially for large datasets, since it leverages numpy's broadcasting to avoid any explicit loops:

# Extract start/end columns as numpy arrays, reshape for broadcasting
df1_starts = df1['start'].to_numpy().reshape(1, -1)
df1_ends = df1['end'].to_numpy().reshape(1, -1)
df2_starts = df2['start'].to_numpy().reshape(-1, 1)
df2_ends = df2['end'].to_numpy().reshape(-1, 1)

# Check if each df2 row is contained in at least one df1 interval
contains_mask = ((df2_starts >= df1_starts) & (df2_ends <= df1_ends)).any(axis=1)

# Filter df2 to get the result
result = df2[contains_mask]
print(result)

输出:

start   value  end
1      3  TEST2    4

Why this works: Broadcasting lets us compare every row in df2 against every row in df1 in one go. The any(axis=1) checks if there's at least one df1 interval that contains the df2 row. This is lightning fast compared to nested loops.

2. 交叉连接+过滤(适合小数据集)

If your dataset is small and you prefer a more explicit approach, you can create a cross join of all df1/df2 row pairs, then filter for matches:

# Add a temporary key to enable cross join
df1['temp_key'] = 1
df2['temp_key'] = 1

# Create all possible row combinations
cross_join = pd.merge(df1, df2, on='temp_key').drop('temp_key', axis=1)

# Filter rows where df2's interval is inside df1's
matches = cross_join[
    (cross_join['start_y'] >= cross_join['start_x']) & 
    (cross_join['end_y'] <= cross_join['end_x'])
]

# Extract and deduplicate the df2 rows (since one df2 row might match multiple df1 rows)
result = matches[['start_y', 'value_y', 'end_y']].rename(
    columns={'start_y':'start', 'value_y':'value', 'end_y':'end'}
).drop_duplicates()

print(result)

Note: This uses more memory because it creates a row for every combination of df1 and df2, so avoid it for large datasets.

3. Apply逐行判断(可读性高,适合小数据)

If you want code that's super readable (even if slightly less efficient), you can use apply to check each df2 row against df1:

def is_contained_in_any_df1_interval(row):
    # Check if this df2 row fits within any df1 interval
    return ((df1['start'] <= row['start']) & (df1['end'] >= row['end'])).any()

# Create a mask for df2 rows that meet the condition
contains_mask = df2.apply(is_contained_in_any_df1_interval, axis=1)

result = df2[contains_mask]
print(result)

This is easier to follow for beginners, but it's still a row-wise operation, so it won't be as fast as the vectorized numpy method for big data.

All of these methods will give you the exact result you're looking for—df2's second row. The numpy broadcasting method is the most "Pandas-idiomatic" since it leans into the vectorized operations that make Pandas so powerful.

内容的提问来源于stack exchange,提问作者E.J

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.01 01:07:43