Pandas 新增与删除列

在实际数据分析中,我们经常需要根据现有数据创建新列,或者移除不需要的列。Pandas 提供了多种灵活的方法来新增和删除列,让你能够轻松调整 DataFrame 的结构。

📌 准备示例数据

import pandas as pd
import numpy as np

df = pd.DataFrame({
    '姓名': ['张三', '李四', '王五', '赵六'],
    '年龄': [28, 35, 42, 29],
    '工资': [8000, 12000, 15000, 9500],
    '部门': ['技术', '销售', '技术', '管理']
})
print(df)

➕ 新增列的方法

1. 直接赋值

最简单的方法,类似字典添加键值对,新列会被添加到末尾。

# 添加常数列
df['入职年份'] = 2020
print(df)

# 根据现有列计算
df['年薪'] = df['工资'] * 12
print(df)

# 添加 Series(需索引对齐)
s = pd.Series([5, 3, 2, 4], index=[0,1,2,3])  # 索引需匹配
df['工龄'] = s
print(df)

2. 使用 insert() 指定位置插入

可以在指定列位置插入新列,而不总是追加到末尾。

# 在索引1的位置(第二列)插入新列
df.insert(1, '性别', ['男', '男', '男', '女'])
print(df)

# 参数说明:loc=位置索引,column=列名,value=值,allow_duplicates=是否允许重复列名
# 如果列名已存在,默认会报错,设置 allow_duplicates=True 可强制添加重复列(不推荐)

3. 使用 assign() 方法

assign() 返回一个新的 DataFrame,可以同时添加多列,且不会修改原 DataFrame(除非重新赋值)。

# 添加多列(可以引用已有列)
df_new = df.assign(
    税后工资=lambda x: x['工资'] * 0.9,
    等级=lambda x: ['高级' if a > 35 else '初级' for a in x['年龄']]
)
print(df_new)

# assign 不会修改原 df
print(df)  # 原 df 没有变化

4. 根据条件创建新列

常用 numpy.where()loc 赋值。

# 使用 np.where
df['工资等级'] = np.where(df['工资'] > 10000, '高', '低')
print(df)

# 使用 loc 进行更复杂的条件赋值
df['类别'] = '其他'
df.loc[df['部门'] == '技术', '类别'] = '核心'
df.loc[df['部门'] == '销售', '类别'] = '业务'
print(df)

5. 使用 apply() 函数

对行或列应用函数生成新列。

# 对每行应用函数
df['简介'] = df.apply(lambda row: f"{row['姓名']} - {row['部门']} - {row['年龄']}岁", axis=1)
print(df)

➖ 删除列的方法

1. 使用 drop() 方法(最常用)

drop() 可以删除行或列,通过 axis=1columns 参数指定删除列。

# 删除单列
df_dropped = df.drop('工龄', axis=1)  # 返回新 DataFrame
print(df_dropped)

# 删除多列
df_dropped = df.drop(['工资等级', '类别'], axis=1)

# 使用 columns 参数更清晰
df_dropped = df.drop(columns=['简介'])

# 原地修改(inplace=True)
df.drop('入职年份', axis=1, inplace=True)

2. 使用 del 语句

类似 Python 字典的删除,直接修改原 DataFrame。

del df['年薪']   # 原地删除
print(df)

3. 使用 pop() 方法

删除指定列并返回该列(类似字典的 pop)。

removed_col = df.pop('性别')
print(removed_col)  # 被删除的列作为 Series 返回
print(df)           # 原 df 已没有 '性别' 列

🧪 综合示例

import pandas as pd
import numpy as np

# 原始数据
df = pd.DataFrame({
    'product': ['A', 'B', 'C', 'D'],
    'price': [100, 250, 175, 300],
    'quantity': [5, 10, 8, 3]
})
print("原始 df:")
print(df)

# 1. 新增列:总价
df['total'] = df['price'] * df['quantity']

# 2. 新增列:利润(假设成本是价格的70%)
df['profit'] = df['total'] * 0.3

# 3. 在第二列位置插入折扣列
df.insert(1, 'discount', [0.1, 0.15, 0.05, 0.2])

# 4. 根据价格高低添加标签
df['price_level'] = np.where(df['price'] > 200, '高', '低')

print("\n新增列后:")
print(df)

# 5. 删除不需要的列
df.drop(['discount', 'profit'], axis=1, inplace=True)

print("\n删除列后:")
print(df)

⚠️ 注意事项

视图与副本:直接赋值修改的是原 DataFrame。使用 assign() 返回新对象,不会修改原数据。使用 drop() 默认返回新对象,需设置 inplace=True 才修改原对象。
列名重复:DataFrame 允许重复列名,但会造成后续操作混乱。除非必要,应避免重复列名。
索引对齐:当用 Series 或数组赋值新列时,Pandas 会根据索引自动对齐。如果索引不匹配,可能会产生 NaN。
性能考虑:在大型 DataFrame 中,使用 assign()drop() 返回新对象会复制数据,可能消耗内存。原地修改(inplace=Truedel)更节省内存。
最佳实践:
  • 新增简单列时,直接赋值最直观;需要在特定位置插入用 insert()
  • 如果需要链式操作或同时添加多列,assign() 很优雅,但注意它返回副本。
  • 删除列推荐使用 drop() 并指定 columns 参数,代码可读性高。
  • 谨慎使用 inplace=True,除非确定要修改原数据且后续不再需要原数据。