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

不使用for循环重构DataFrame的Pythonic(Pandas风格)实现方法

Pandas风格的DataFrame转换:彻底告别For循环

这问题问得太对了——用Pandas处理DataFrame结构转换,绝对要抛弃for循环,这才是Pandas的正确打开方式!核心思路就是用Pandas内置的矢量化操作和数据重塑工具,既简洁又高效,完全符合Python/Pandas风格。我给你分场景拆解几种常用方法:

一、数据重塑:宽表↔长表转换

这是最常见的结构转换场景,Pandas专门提供了工具函数:

  • 宽表转长表:用melt()
    比如你有一张按用户+多科目分数的宽表,要转成用户-科目-分数的长表:
    import pandas as pd
    # 原宽表
    df_wide = pd.DataFrame({
        'Name': ['Alice', 'Bob'],
        'Math': [85, 90],
        'English': [78, 82],
        'Science': [92, 88]
    })
    # 转换成长表
    df_long = df_wide.melt(
        id_vars='Name',  # 保留的主键列
        var_name='Subject',  # 原列名转成的新列名
        value_name='Score'  # 原列值转成的新列名
    )
    
  • 长表转宽表:用pivot()或pivot_table()
    如果要把上面的长表转回宽表,用pivot();如果有重复主键需要聚合,就用pivot_table():
    # 长表转宽表
    df_wide_new = df_long.pivot(
        index='Name',
        columns='Subject',
        values='Score'
    ).reset_index()
    

二、列衍生/批量计算转换

如果是要基于现有列生成新列,或者批量修改列,直接用矢量化运算就行,比for循环快几个数量级:

  • 直接矢量化运算:比如新增一列是多列的求和
    df['Total_Score'] = df['Math'] + df['English'] + df['Science']
    
  • 用assign()做链式衍生:适合一次性生成多列,代码更整洁
    df = df.assign(
        Total_Score=lambda x: x['Math'] + x['English'] + x['Science'],
        Avg_Score=lambda x: x['Total_Score'] / 3
    )
    
  • 专属访问器处理特殊类型:比如字符串、日期的批量转换
    # 字符串批量转大写
    df['Name_Upper'] = df['Name'].str.upper()
    # 日期字符串批量转日期类型
    df['Exam_Date'] = pd.to_datetime(df['Exam_Date_Str']).dt.date
    

三、筛选+重组结构

如果是要筛选部分行/列,再重组新的DataFrame,用loc/iloc配合concat/merge:

  • 直接筛选重组:
    # 筛选数学分数>80的行,只保留姓名和数学列,并重命名列
    new_df = df.loc[df['Math']>80, ['Name', 'Math']].rename(columns={'Math':'Math_Score'})
    
  • 合并多个片段:用concat(行/列合并)或merge(关联合并)
    # 按行合并两个筛选后的DataFrame片段
    df_part1 = df.loc[df['Name']=='Alice', :]
    df_part2 = df.loc[df['Name']=='Bob', :]
    new_df = pd.concat([df_part1, df_part2], axis=0)
    

四、分组后结构转换

如果需要按分组做转换,用groupby配合transform或agg:

# 给每个班级添加班级内的总分平均分
df['Class_Avg'] = df.groupby('Class')['Total_Score'].transform('mean')
# 按班级聚合生成新的统计DataFrame
grouped_df = df.groupby('Class').agg(
    Avg_Score=('Total_Score', 'mean'),
    Max_Score=('Total_Score', 'max')
).reset_index()

避坑提醒

绝对不要用iterrows()/itertuples()这类伪循环方法——它们本质还是逐行遍历,效率极低,完全不符合Pandas的设计理念。只要是你想用for循环做的操作,99%都能找到对应的矢量化方法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 03:28:40