35. append 与 assign
1. 概述
append和assign是 DataFrame 的便捷方法:
append:用于添加行(注意:Pandas 2.0+ 已弃用,推荐使用concat)assign:用于添加列,返回新 DataFrame
importpandasaspdimportnumpyasnp# 创建示例数据np.random.seed(42)df=pd.DataFrame({'姓名':['张三','李四','王五'],'年龄':[25,30,28],'城市':['北京','上海','广州']})print("原始数据:")print(df)2. append 添加行
2.1 基本用法(Pandas 1.x)
# 注意:append 在 Pandas 2.0+ 已弃用,推荐使用 concat# 以下代码仅供参考# 添加单行new_row=pd.DataFrame({'姓名':['赵六'],'年龄':[32],'城市':['深圳']})df_appended=pd.concat([df,new_row],ignore_index=True)print("添加单行:")print(df_appended)# 添加多行new_rows=pd.DataFrame({'姓名':['钱七','孙八'],'年龄':[35,27],'城市':['杭州','成都']})df_appended=pd.concat([df,new_rows],ignore_index=True)print("\n添加多行:")print(df_appended)2.2 使用 concat 替代 append
# 推荐方式:使用 concat# 添加字典作为新行new_row_dict={'姓名':'周九','年龄':29,'城市':'武汉'}df_new=pd.concat([df,pd.DataFrame([new_row_dict])],ignore_index=True)print("使用 concat 添加字典行:")print(df_new)# 添加 Series 作为新行new_row_series=pd.Series({'姓名':'吴十','年龄':31,'城市':'西安'})df_new=pd.concat([df,pd.DataFrame([new_row_series])],ignore_index=True)print("\n使用 concat 添加 Series 行:")print(df_new)3. assign 添加列
3.1 基本用法
assign返回新的 DataFrame,不会修改原数据。
# 添加常量列df_new=df.assign(等级='普通')print("添加常量列:")print(df_new)# 添加计算列df_new=df.assign(年龄_翻倍=df['年龄']*2)print("\n添加计算列:")print(df_new)# 添加多个列df_new=df.assign(年龄_翻倍=df['年龄']*2,年龄_平方=df['年龄']**2,等级='普通')print("\n添加多个列:")print(df_new)3.2 使用 lambda 表达式
# 使用 lambda 引用其他新列df_new=df.assign(年龄_翻倍=lambdax:x['年龄']*2,年龄_平方=lambdax:x['年龄']**2,总和=lambdax:x['年龄_翻倍']+x['年龄_平方'])print("使用 lambda:")print(df_new)3.3 条件列
# 根据条件创建列df_new=df.assign(年龄段=df['年龄'].apply(lambdax:'青年'ifx<30else'中年'))print("条件列:")print(df_new)# 使用 numpy wheredf_new=df.assign(是否成年=np.where(df['年龄']>=18,'是','否'))print("\n使用 np.where:")print(df_new)4. 链式操作
# assign 支持链式调用result=(df.assign(年龄_翻倍=df['年龄']*2).assign(年龄_平方=df['年龄']**2).assign(总和=lambdax:x['年龄_翻倍']+x['年龄_平方']).assign(等级='普通'))print("链式 assign:")print(result)5. 添加行和列的组合
# 先添加列,再添加行df_new=(df.assign(年龄_翻倍=df['年龄']*2).assign(等级='普通'))new_row=pd.DataFrame({'姓名':['赵六'],'年龄':[32],'城市':['深圳'],'年龄_翻倍':[64],'等级':['普通']})result=pd.concat([df_new,new_row],ignore_index=True)print("添加列后再添加行:")print(result)6. 完整示例:员工数据更新
# 创建员工数据print("="*60)print("员工数据更新(append + assign)")print("="*60)employees=pd.DataFrame({'员工ID':[1001,1002,1003],'姓名':['张三','李四','王五'],'基本工资':[5000,6000,5500],'入职年份':[2020,2019,2021]})print("\n原始员工数据:")print(employees)# 1. 添加新员工print("\n1. 添加新员工:")new_employee=pd.DataFrame({'员工ID':[1004],'姓名':['赵六'],'基本工资':[5800],'入职年份':[2022]})employees=pd.concat([employees,new_employee],ignore_index=True)print(employees)# 2. 添加计算列(工龄)print("\n2. 添加工龄列:")employees=employees.assign(工龄=2026-employees['入职年份'],工龄工资=employees['基本工资']*0.05*(2026-employees['入职年份']))print(employees)# 3. 添加绩效等级print("\n3. 添加绩效等级:")np.random.seed(42)employees=employees.assign(绩效=np.random.choice(['A','B','C','D'],len(employees)),绩效奖金=lambdax:x['基本工资']*(0.3ifx['绩效']=='A'else0.2ifx['绩效']=='B'else0.1))print(employees)# 4. 计算总收入print("\n4. 计算总收入:")employees=employees.assign(总收入=lambdax:x['基本工资']+x['工龄工资']+x['绩效奖金'])print(employees[['姓名','基本工资','工龄工资','绩效奖金','总收入']])# 5. 添加新员工(使用 assign 保持一致)print("\n5. 批量添加新员工:")new_employees=pd.DataFrame({'员工ID':[1005,1006],'姓名':['钱七','孙八'],'基本工资':[6200,5900],'入职年份':[2023,2024]})# 对新员工应用相同的转换new_employees=new_employees.assign(工龄=2026-new_employees['入职年份'],工龄工资=new_employees['基本工资']*0.05*(2026-new_employees['入职年份']),绩效=np.random.choice(['A','B','C','D'],len(new_employees)),绩效奖金=lambdax:x['基本工资']*(0.3ifx['绩效']=='A'else0.2ifx['绩效']=='B'else0.1),总收入=lambdax:x['基本工资']+x['工龄工资']+x['绩效奖金'])employees=pd.concat([employees,new_employees],ignore_index=True)print(employees[['姓名','基本工资','总收入']])# 6. 最终统计print("\n6. 工资统计:")print(f"平均基本工资:{employees['基本工资'].mean():.0f}")print(f"平均总收入:{employees['总收入'].mean():.0f}")print(f"最高收入:{employees.loc[employees['总收入'].idxmax(),'姓名']}")7. append vs concat 对比
| 特性 | append(已弃用) | concat |
|---|---|---|
| Pandas 2.0+ 支持 | ❌ 已弃用 | ✅ 推荐 |
| 语法 | df.append(new_row) | pd.concat([df, new_row]) |
| 多行添加 | 支持 | 支持 |
| 忽略索引 | ignore_index=True | ignore_index=True |
8. assign 特点
| 特点 | 说明 |
|---|---|
| 返回新对象 | 不修改原 DataFrame |
| 链式调用 | 支持连续 assign |
| lambda 支持 | 可引用之前创建的列 |
| 批量添加 | 一次可添加多列 |
9. 总结
| 操作 | 推荐方法 | 示例 |
|---|---|---|
| 添加行 | pd.concat() | pd.concat([df, new_row], ignore_index=True) |
| 添加常量列 | assign() | df.assign(new_col=value) |
| 添加计算列 | assign() | df.assign(new_col=df['col'] * 2) |
| 添加多列 | assign() | df.assign(col1=val1, col2=val2) |
| 链式添加 | assign().assign() | df.assign(a=1).assign(b=2) |
10. 模块六总结
恭喜你完成了模块六:数据合并与连接!
你已掌握:
- ✅ concat 拼接(垂直/水平)
- ✅ merge 合并(内/左/右/外连接)
- ✅ merge 高级用法(指示器、索引合并、验证)
- ✅ join 方法(基于索引的便捷合并)
- ✅ append 与 assign(添加行和列)