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

如何按分类生成含最值的等间距DataFrame行?缩减行数求助

这需求很常见,而且咱们可以利用val1在每个分类里递增的特性,用高效的方法来实现,不用挨个循环查找!下面是具体的步骤和代码:

实现步骤&代码

1. 先准备好原数据

首先导入库并创建你给出的DataFrame:

import pandas as pd
import numpy as np

dictionary = {'Category':['a','a','a','a','a','a','a','a','b','b','b','b','b','b','b'], 
              'val1':[11,13,14,17,18,21,22,25,2,8,9,13,15,16,19], 
              'val2':[1,0,5,1,4,3,5,9,4,1,5,2,4,0,3]}
df = pd.DataFrame(dictionary)

2. 生成每个分类的等间距目标点

我们先按Category分组,拿到每个组的val1最小值和最大值,然后用np.linspace生成包含首尾的5个等间距点:

# 分组计算每个分类的val1范围,生成5个等间距点并拆成单独行
target_points = df.groupby('Category')['val1'].agg(['min', 'max']).apply(
    lambda x: np.linspace(x['min'], x['max'], 5), axis=1
).explode().reset_index(name='target_val1')
# 转成float类型,避免后续匹配出问题
target_points['target_val1'] = target_points['target_val1'].astype(float)

3. 高效匹配最接近的原数据行

因为每个分类的val1是递增的,用pd.merge_asof做最近邻匹配是最优解——这个函数专门针对有序键的合并,比手动循环查找效率高N倍:

# 先确保两边的数据集都按Category和目标键排序(merge_asof要求的)
df_sorted = df.sort_values(['Category', 'val1']).reset_index(drop=True)
target_points_sorted = target_points.sort_values(['Category', 'target_val1']).reset_index(drop=True)

# 执行最近邻匹配,direction='nearest'表示找最接近的val1
result = pd.merge_asof(
    target_points_sorted,
    df_sorted,
    left_on='target_val1',
    right_on='val1',
    by='Category',
    direction='nearest'
)

# 整理结果列的顺序,按分类排序
final_df = result[['Category', 'val1', 'val2', 'target_val1']].sort_values(['Category', 'val1']).reset_index(drop=True)

看一下最终结果

打印final_df会得到每个分类5行的数据,每行对应等间距目标点匹配到的最接近的原数据行:

Category  val1  val2  target_val1
0        a    11     1         11.0
1        a    14     5         15.0
2        a    18     4         19.0
3        a    22     5         23.0
4        a    25     9         25.0
5        b     2     4          2.0
6        b     9     5          6.75
7        b    15     4         11.5
8        b    16     0         16.25
9        b    19     3         19.0

补充说明

  • 如果你的数据集很大,这个方法的优势会更明显,因为merge_asof是基于有序键的向量操作,比循环每个目标点查找要高效得多。
  • 如果想要匹配"不超过目标值的最大val1"或者"不小于目标值的最小val1",只需要把direction参数改成backward或者forward就行,非常灵活。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:36:40