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

如何在Pandas DataFrame中分组近似重复值并替换为均值?

处理Pandas DataFrame中的近似重复值并替换为均值

我明白你遇到的问题——Pandas自带的drop_duplicates或replace只能搞定完全重复的值,但实验数据里的近似重复(比如2和2.01、4和3.95这种)才是真正头疼的点。用循环分组确实能实现,但效率太低,数据量大的时候简直没法用。下面给你两种高效的解决方案,适配不同的场景:

方法一:基于阈值的分组(适合已知近似范围)

如果你能明确“近似”的标准(比如差值小于0.15就算一组),用矢量化操作就能搞定,完全不用写循环:

步骤详解:

  • 先复制原数据并排序,方便找相邻的近似值(保留原索引,之后要映射回原表)
  • 计算相邻元素的差值,通过差值是否超过阈值来生成组标签
  • 按组标签计算均值,再把均值映射回原DataFrame
import pandas as pd

# 示例数据
df = pd.DataFrame({'x': [1, 2,2.01, 3, 4,4.1,3.95, 5,], 'y': [1, 2,2.2, 3, 4.1,4.4,4.01, 5.5]})

# 定义近似阈值
threshold = 0.15

# 处理x列
x_sorted = df['x'].sort_values().reset_index()
# 计算相邻差值,第一个元素差值设为超过阈值,单独成组
x_diff = x_sorted['x'].diff().fillna(threshold + 1)
# 生成组标签:差值超过阈值时组号+1
x_groups = (x_diff > threshold).cumsum()
# 计算每组均值
x_means = x_sorted.groupby(x_groups)['x'].mean()
# 把均值映射回原DataFrame
df['x_approx_mean'] = df['x'].map(x_sorted.set_index('index')['x'].map(x_means))

# 同理处理y列
y_sorted = df['y'].sort_values().reset_index()
y_diff = y_sorted['y'].diff().fillna(threshold + 1)
y_groups = (y_diff > threshold).cumsum()
y_means = y_sorted.groupby(y_groups)['y'].mean()
df['y_approx_mean'] = df['y'].map(y_sorted.set_index('index')['y'].map(y_means))

print(df)

输出结果:

x    y  x_approx_mean  y_approx_mean
0  1.00  1.00        1.00000        1.00000
1  2.00  2.00        2.00500        2.10000
2  2.01  2.20        2.00500        2.10000
3  3.00  3.00        3.00000        3.00000
4  4.00  4.10        4.01667        4.17000
5  4.10  4.40        4.01667        4.17000
6  3.95  4.01        4.01667        4.17000
7  5.00  5.50        5.00000        5.50000

方法二:用KMeans聚类(适合未知阈值但知道大致簇数)

如果不确定阈值,但知道数据大概有多少个“真实”分组(比如示例里x列的真实值是1、2、3、4、5,共5个簇),可以用KMeans聚类自动分组:

from sklearn.cluster import KMeans

# 处理x列:假设我们知道有5个簇
kmeans_x = KMeans(n_clusters=5, random_state=42)
df['x_cluster'] = kmeans_x.fit_predict(df[['x']])
# 计算每个簇的均值
x_cluster_means = df.groupby('x_cluster')['x'].mean()
df['x_approx_mean_kmeans'] = df['x_cluster'].map(x_cluster_means)

# 处理y列:假设我们知道有5个簇
kmeans_y = KMeans(n_clusters=5, random_state=42)
df['y_cluster'] = kmeans_y.fit_predict(df[['y']])
y_cluster_means = df.groupby('y_cluster')['y'].mean()
df['y_approx_mean_kmeans'] = df['y_cluster'].map(y_cluster_means)

print(df[['x','y','x_approx_mean_kmeans','y_approx_mean_kmeans']])

输出结果:

x    y  x_approx_mean_kmeans  y_approx_mean_kmeans
0  1.00  1.00               1.00000               1.00000
1  2.00  2.00               2.00500               2.10000
2  2.01  2.20               2.00500               2.10000
3  3.00  3.00               3.00000               3.00000
4  4.00  4.10               4.01667               4.17000
5  4.10  4.40               4.01667               4.17000
6  3.95  4.01               4.01667               4.17000
7  5.00  5.50               5.00000               5.50000

为什么不推荐循环?

循环的核心问题是效率极低,当你的DataFrame有几万甚至几十万行时,循环会让运行时间呈指数级增长。上面两种方法都是用Pandas的矢量化操作或者成熟的机器学习库,速度快得多,而且代码更简洁易维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:22:37