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

如何提取Pandas DataFrame每行的10个最大峰值及对应列名?

遍历DataFrame提取每行峰值及对应列名并追加到行尾

问题背景

我有理论思路,但试了iteritems、iterrows、itertuples、loc、iloc还有它们的组合,甚至用行列数做range循环,都没法遍历每行的每个值,同时提取所需值和对应的列名。

示例DataFrame

frequency_bin_1frequency_bin_2frequency_bin_3frequency_bin_4frequency_bin_5
0.22222220.333333330.444444440.222222220.11111111
0.111111110.22222220.333333330.444444440.33333333
0.111111110.22222220.111111110.222222220.11111111
0.111111110.22222220.111111110.222222220.33333333
0.111111110.22222220.111111110.444444440.33333333

需求

提取每行峰值(含并列峰值)及对应列名,示例结果:

  • 第1行峰值:frequency_bin_3
  • 第2行峰值:frequency_bin_4
  • 第3行峰值:frequency_bin_2、frequency_bin_4
  • 第4行峰值:frequency_bin_2、frequency_bin_5
  • 第5行峰值:frequency_bin_2、frequency_bin_4

我的思路草稿

"""
遍历DataFrame的每一行
    遍历该行的每个值
        将第一个值设为'current'
        如果下一个值大于'current'
            用下一个值替换'current'
        如果下一个值小于'current'
            将'current'的值添加到peak_values列表
            将'current'的列名添加到peak_columns列表
            (注:这两个列表可改用其他数据结构,比如字典,方便后续操作)
    完成该行遍历后
        仅保留10个最大的峰值及其对应列名
        将peak_values和peak_columns列表交替追加到该行末尾
            (列名、列值、列名、列值依次排列)
"""

现在卡壳了,不知道是不是该换数据结构(比如把每行转成列表处理后再追加回DataFrame),我是编程新手,求实用建议。


解决方案

方法1:用apply逐行处理(简洁高效)

Pandas的apply方法可以直接对每行执行自定义函数,结合行的索引和值列表,能轻松提取峰值:

import pandas as pd

# 构造示例数据
data = {
    'frequency_bin_1': [0.2222222, 0.11111111, 0.11111111, 0.11111111, 0.11111111],
    'frequency_bin_2': [0.33333333, 0.2222222, 0.2222222, 0.2222222, 0.2222222],
    'frequency_bin_3': [0.44444444, 0.33333333, 0.11111111, 0.11111111, 0.11111111],
    'frequency_bin_4': [0.22222222, 0.44444444, 0.22222222, 0.22222222, 0.44444444],
    'frequency_bin_5': [0.11111111, 0.33333333, 0.11111111, 0.33333333, 0.33333333]
}
df = pd.DataFrame(data)

def extract_peaks(row):
    peaks = []
    cols = row.index.tolist()
    values = row.tolist()
    
    # 找局部峰值(比左右相邻值大)
    for i in range(1, len(values)-1):
        if values[i] > values[i-1] and values[i] > values[i+1]:
            peaks.append( (cols[i], values[i]) )
    # 处理首尾元素(如果比相邻元素大也算峰值)
    if values[0] > values[1]:
        peaks.append( (cols[0], values[0]) )
    if values[-1] > values[-2]:
        peaks.append( (cols[-1], values[-1]) )
    
    # 按峰值大小降序,取前10个
    peaks_sorted = sorted(peaks, key=lambda x: x[1], reverse=True)[:10]
    
    # 交替展开列名和值
    result = []
    for col, val in peaks_sorted:
        result.append(col)
        result.append(val)
    
    return pd.Series(result)

# 生成峰值扩展列
peak_df = df.apply(extract_peaks, axis=1)
# 给扩展列命名
peak_df.columns = [f'peak_col_{i//2+1}' if i%2==0 else f'peak_val_{i//2+1}' for i in range(peak_df.shape[1])]
# 合并原数据和峰值列
final_df = pd.concat([df, peak_df], axis=1)

# 输出到CSV
final_df.to_csv('peaks_result.csv', index=False)

方法2:逐行遍历(直观易懂,适合新手)

如果觉得apply太抽象,用iterrows逐行循环更直观,容易理解每一步:

import pandas as pd

df = pd.DataFrame(data)  # 同上构造数据

final_rows = []

for idx, row in df.iterrows():
    peaks = []
    cols = row.index.tolist()
    values = row.values.tolist()
    
    # 峰值判断逻辑和方法1一致
    for i in range(1, len(values)-1):
        if values[i] > values[i-1] and values[i] > values[i+1]:
            peaks.append( (cols[i], values[i]) )
    if values[0] > values[1]:
        peaks.append( (cols[0], values[0]) )
    if values[-1] > values[-2]:
        peaks.append( (cols[-1], values[-1]) )
    
    # 排序取前10
    peaks_sorted = sorted(peaks, key=lambda x: x[1], reverse=True)[:10]
    
    # 把原行数据转成列表,追加峰值的列名和值
    row_list = row.values.tolist()
    for col, val in peaks_sorted:
        row_list.append(col)
        row_list.append(val)
    
    final_rows.append(row_list)

# 生成新列名
new_cols = df.columns.tolist()
for i in range(1, len(peaks_sorted)+1):
    new_cols.append(f'peak_col_{i}')
    new_cols.append(f'peak_val_{i}')

# 构造最终DataFrame并输出
final_df = pd.DataFrame(final_rows, columns=new_cols)
final_df.to_csv('peaks_result.csv', index=False)

关键调整说明

如果你的需求是找全局最大值的所有列(比如第3行的0.222是全局最大值,对应bin2和bin4),可以简化峰值判断逻辑:

def extract_global_peaks(row):
    max_val = row.max()
    # 提取所有值等于最大值的列名和值
    peaks = [ (col, val) for col, val in row.items() if val == max_val ]
    peaks_sorted = sorted(peaks, key=lambda x: x[1], reverse=True)[:10]
    # 后续展开和追加逻辑同上

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 05:24:12