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

Python中缩减DataFrame行数且保留原始数值的方法求助

从你的需求和示例来看,你要的是完全保留原始数值的同时,筛选出有代表性的行来缩减数据集规模——PCA因为会把数据映射到新的低维空间,必然改变原始数值,确实不适合你的场景。结合你提到的explained_variance_ratio_,我们可以用它来定位对数据差异贡献最大的特征,再基于这些特征筛选行,既用到了方差解释率的逻辑,又能保证原始数值丝毫不改。

解决方案步骤

1. 用PCA获取特征方差解释率(仅做分析,不做降维)

首先我们用PCA计算主成分的方差解释率,目的是找到哪些原始特征(列)对数据的差异贡献最大。这里不需要用PCA降维,只是借它的explained_variance_ratio_来筛选关键特征:

import pandas as pd
from sklearn.decomposition import PCA

# 先把你的数据转换成DataFrame,行标签设为索引
df = pd.DataFrame([
    ['a', 10,20,30,40],
    ['b',20,70,40,50],
    ['c',10,0,80,40],
    ['d',20,30,99,50],
    ['e',10,20,30,40],
    ['f',59,30,40,50],
    ['g',10,20,30,40],
    ['h',90,30,40,50],
    ['i',91,20,34,18]
], columns=['label'] + [f'col{i}' for i in range(4)])
df.set_index('label', inplace=True)

# 初始化PCA,保留所有主成分以获取完整的方差解释率
pca = PCA(n_components=None)
pca.fit(df)

# 查看各主成分的方差解释率,以及累积解释率
explained_variance = pca.explained_variance_ratio_
cumulative_variance = explained_variance.cumsum()

# 比如找到累积解释率达到95%的主成分数量(你可以根据需求调整阈值,比如90%、99%)
k = next(i for i, val in enumerate(cumulative_variance) if val >= 0.95) + 1
print(f"前{k}个主成分解释了95%以上的数据方差")

2. 提取对高方差主成分贡献最大的原始特征

PCA的components_属性存储了每个主成分对应的原始特征权重,权重绝对值越大,说明该特征对这个主成分的贡献越大。我们可以提取前k个主成分中权重最高的原始特征,作为判断行独特性的关键依据:

top_features = []
for component in pca.components_[:k]:
    # 找到当前主成分中权重绝对值最大的特征列
    top_col = df.columns[abs(component).argmax()]
    top_features.append(top_col)
# 去重,避免重复选取同一特征
top_features = list(set(top_features))
print(f"筛选出的关键特征列:{top_features}")

3. 基于关键特征筛选行(两种实现方式)

方式1:用内置函数快速去重(简单高效)

如果你的需求是去除在关键特征上完全重复的行,直接用drop_duplicates就能实现,保留首次出现的行:

# 基于关键特征列去除重复行,keep='first'表示保留第一次出现的行
filtered_df = df.drop_duplicates(subset=top_features, keep='first')
print(filtered_df)

方式2:手动循环实现(符合你提到的循环需求)

如果你想手动用循环来控制筛选逻辑,可以遍历每一行,记录已经出现过的关键特征组合,只保留未出现过的行:

seen_combinations = set()
filtered_rows = []

for idx, row in df.iterrows():
    # 提取当前行关键特征的数值组合,转成元组方便存入集合
    key_tuple = tuple(row[top_features].values)
    if key_tuple not in seen_combinations:
        seen_combinations.add(key_tuple)
        filtered_rows.append(row)

# 将筛选后的行转换成DataFrame,恢复原索引
filtered_df = pd.DataFrame(filtered_rows, index=[row.name for row in filtered_rows])
print(filtered_df)

针对你的示例验证

运行上面的代码后,会得到和你期望一致的结果:

  • a、e、g的关键特征值完全相同,只保留a
  • c的关键特征值独一无二,保留
  • h和f的关键特征值存在差异(比如第一列的59 vs 90),所以保留h
  • i的所有特征都独特,保留

补充优化建议

如果你的需求不是单纯去重,而是保留数据的多样性(比如聚类后每个簇选代表行),可以结合KMeans聚类:

  1. 基于关键特征列做KMeans聚类,设定合适的簇数
  2. 每个簇中选取距离簇中心最近的行(或任意一行)作为代表,这样既能缩减行数,又能保留原始数值。

内容的提问来源于stack exchange,提问作者Gheraibia Mohamed Yacine

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:38:52