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

如何基于df1索引提取df2中对应行的前后行?

解决方案:提取df2中与df1索引相邻的行

首先我得明确你的需求:你想要从df2里筛选出那些索引恰好是df1各索引的前后相邻邻居的行——也就是对df1的每一个索引值,找到df2中比它小的最大索引(前序邻居)和比它大的最小索引(后序邻居),最后把这些行汇总起来(自动去重)。

第一步:构造示例数据

先把你给出的两个DataFrame用pandas正确构造出来,方便后续操作:

import pandas as pd

# 构造df1
df1 = pd.DataFrame(
    data=[[1, 'alpha'], [3, 'alpha'], [5, 'alpha'], [9, 'alpha']],
    index=[3, 18, 125, 230],
    columns=['Id', 'B']
)

# 构造df2
df2 = pd.DataFrame(
    data=[
        [21, 'Beta'], [33, 'Beta'], [120, 'Beta'], [36, 'Beta'],
        [32, 'Beta'], [71, 'Beta'], [210, 'Beta'], [53, 'Beta'],
        [22, 'Beta'], [1227, 'Beta'], [11, 'Beta'], [7, 'Beta'], [18, 'Beta']
    ],
    index=[1, 2, 5, 7, 10, 14, 15, 21, 123, 127, 128, 227, 235],
    columns=['Id', 'B']
)

第二步:核心实现代码

我们用bisect模块做二分查找,快速定位每个df1索引在df2索引中的前后邻居,效率很高(尤其是当数据量大的时候):

import bisect

# 获取df2排序后的索引列表(二分查找需要有序序列)
df2_sorted_indices = sorted(df2.index)

# 用集合存储目标索引,自动去重
target_indices = set()

# 遍历df1的每一个索引
for idx in df1.index:
    # 找到当前索引在df2有序索引中的插入位置
    insert_pos = bisect.bisect_left(df2_sorted_indices, idx)
    
    # 提取前序邻居:如果插入位置不是第一个,取前一个索引
    if insert_pos > 0:
        target_indices.add(df2_sorted_indices[insert_pos - 1])
    # 提取后序邻居:如果插入位置不是最后一个,取当前位置的索引
    if insert_pos < len(df2_sorted_indices):
        target_indices.add(df2_sorted_indices[insert_pos])

# 从df2中提取目标行,保持原df2的行顺序
result_df = df2.loc[df2.index.isin(target_indices)]

# 打印结果
print(result_df)

代码解释

  1. 排序df2索引:把df2的索引转成有序列表,这样才能用二分查找快速定位邻居,避免遍历整个df2索引(数据量大时速度差距明显)。
  2. 二分查找定位:bisect_left会返回当前df1索引应该插入到df2有序索引中的位置,这个位置左边的元素都小于当前索引,右边的都大于等于当前索引。
  3. 收集邻居索引:根据插入位置,分别取出前一个(比当前df1索引小的最大值)和后一个(比当前df1索引大的最小值)索引,用集合存储自动去重。
  4. 提取目标行:用loc和isin筛选出df2中符合条件的行,保持原df2的行顺序;如果想要按索引排序后的顺序,可以用df2.reindex(sorted(target_indices))。

运行结果

最终得到的result_df会包含df2中索引为2、5、15、21、123、127、227、235的行,完全符合你提到的期望输出范围。

内容的提问来源于stack exchange,提问作者Snowfire777

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:42:49