【pandas】-1-读取数据
【pandas】-2-数据查询
【pandas】-3-Pandas 索引
4. Pandas 索新增列,assign,applay,map使用
在 Pandas 中,有多种方式可以新增数据列。我将展示最常用的几种方法,并通过一个示例演示它们的应用。
常用新增列方法
- 直接赋值 - 最常用的方式
- 使用
assign()
方法 - 函数式编程风格,返回新 DataFrame - 使用
apply()
方法 - 基于函数计算新列 - 使用
insert()
方法 - 在指定位置插入列 - 使用条件逻辑 -
np.where()
或np.select()
,注意np 是numpy
示例
python
import pandas as pd
import numpy as np
# 创建示例数据
df = pd.DataFrame({
'A': range(1, 6),
'B': range(10, 15),
'C': ['p', 'q', 'r', 's', 't']
})
print("原始数据:")
print(df)
# 各种新增列的方法
# 1. 直接赋值(最常用)
df['D'] = df['A'] + df['B']
df['E'] = df['C'].str.upper()
# 2. 使用assign()方法
df = df.assign(F=lambda x: x['A'] * 2)
# 3. 使用apply()方法
df['G'] = df.apply(lambda row: row['A'] + row['B'] if row['A'] > 2 else row['A'], axis=1)
# 4. 使用insert()方法在指定位置插入
df.insert(2, 'H', [100, 200, 300, 400, 500])
# 5. 使用条件逻辑
df['I'] = np.where(df['A'] > 3, 'high', 'low')
print("\n新增列后的数据:")
print(df)
# 各列说明
print("\n列说明:")
print("D = A + B")
print("E = C的大写形式")
print("F = A * 2 (使用assign创建)")
print("G = 条件计算: A>2时A+B,否则A")
print("H = 在位置2插入的固定值")
print("I = 条件判断: A>3时为'high',否则'low'")
最常用的方法
在实际工作中,最常用的新增列方法是:
- 直接赋值 - 简单直观,适用于大多数场景
- assign()方法 - 适合函数式编程和链式操作
- 条件逻辑(np.where) - 用于基于条件的列创建
直接赋值是最简单高效的方式,适用于大多数情况。assign()方法在需要保持原DataFrame不变或进行链式操作时非常有用。条件逻辑则常用于数据分箱和分类变量的创建。
你可以运行上述代码查看各种方法的效果,并根据自己的需求选择最适合的方式。
assign
主要特点
- 不修改原 DataFrame:返回一个新的 DataFrame
- 支持链式操作 :可以连续调用多个
assign()
- 支持 lambda 函数:可以使用 lambda 表达式引用其他列
优点与适用场景
- 函数式编程:适合在数据处理的管道操作中使用
- 代码可读性:链式操作使代码更加清晰
- 不修改原数据:避免意外修改原始数据
注意事项
assign()
返回的是新 DataFrame,原始 DataFrame 不会被修改- 如果需要在原 DataFrame 上修改,需要将结果赋值回原变量
- 在同一
assign()
调用中,后面定义的列可以引用前面定义的列
assign()
方法是 Pandas 函数式编程风格的重要组成部分,特别适合在数据清洗和转换的管道操作中使用。
applay()
python
import pandas as pd
import numpy as np
# 创建示例数据
df = pd.DataFrame({
'A': range(1, 6),
'B': range(10, 15),
'C': ['p', 'q', 'r', 's', 't']
})
print("原始数据:")
print(df)
# 对 Series 的每个元素应用函数
df['A_squared'] = df['A'].apply(lambda x: x**2)
print("\nA列的平方:")
print(df['A_squared'])
print("--------------------------")
# 使用自定义函数
def categorize_value(x):
if x > 3:
return 'High'
elif x > 1:
return 'Medium'
else:
return 'Low'
df['A_category'] = df['A'].apply(categorize_value)
print("\nA列的分类:")
print(df['A_category'])
print("--------------------------")
# 创建包含缺失值的数据
df_with_nan = pd.DataFrame({
'A': [1, 2, np.nan, 4, 5],
'B': [10, np.nan, 30, 40, 50],
'C': ['p', 'q', 'r', 's', 't']
})
# 使用 apply 处理缺失值
df_with_nan['A_filled'] = df_with_nan['A'].apply(
lambda x: 0 if pd.isna(x) else x
)
print("\n处理缺失值后的A列:")
print(df_with_nan['A_filled'])
性能考虑
虽然 apply()
非常灵活,但它的性能通常不如 Pandas 的内置向量化操作。对于大型数据集,应该优先考虑使用向量化操作,只有在必要时才使用 apply()
。
与相关方法的比较
- apply() vs map() :
apply()
可以用于 DataFrame 和 Seriesmap()
只能用于 Series,对每个元素应用函数
- apply() vs applymap() :
apply()
沿着轴应用函数applymap()
对 DataFrame 的每个元素应用函数
- apply() vs transform() :
apply()
可以返回聚合结果或转换后的数据transform()
总是返回与原始数据相同形状的结果
特点:
- 尽量使用 Pandas 的内置向量化操作,它们通常比
apply()
更快 - 当需要复杂逻辑时,使用
apply()
配合自定义函数 - 对于简单的元素级操作,考虑使用
map()
或向量化操作 - 使用
axis
参数明确指定是处理行还是列
apply()
方法是 Pandas 中非常强大的工具,特别适合处理需要自定义逻辑的复杂数据转换任务。通过合理使用,可以大大增强数据处理的灵活性和能力。
map 方法
python
import pandas as pd
import numpy as np
# 创建数值型 Series
s_numeric = pd.Series([1, 2, 3, 4, 5])
print("\n数值型 Series:")
print(s_numeric)
# 创建映射 Series
mapping_series = pd.Series(['small', 'medium', 'large'], index=[1, 2, 3])
print("\n映射 Series:")
print(mapping_series)
# 使用 Series 进行映射
s_mapped_series = s_numeric.map(mapping_series)
print("\n使用 Series 映射后的结果:")
print(s_mapped_series)
print("---------------------------")
# 创建包含缺失值的数据
s_with_nan = pd.Series([1, 2, np.nan, 4, 5])
print("\n包含缺失值的 Series:")
print(s_with_nan)
# 默认情况下,map 会处理 NaN 值
s_mapped_nan = s_with_nan.map(lambda x: x*2 if pd.notna(x) else np.nan)
print("\n处理 NaN 后的结果:")
print(s_mapped_nan)
# 使用 na_action='ignore' 参数
s_ignore_nan = s_with_nan.map(lambda x: x*2, na_action='ignore')
print("\n使用 na_action='ignore' 后的结果:")
print(s_ignore_nan)
与相关方法的比较
- map() vs apply() :
map()
只能用于 Series,对每个元素应用函数或映射apply()
可以用于 DataFrame 和 Series,功能更强大
- map() vs replace() :
map()
主要用于值转换和映射replace()
主要用于值替换,支持更复杂的替换模式
- map() vs applymap() :
map()
用于 Seriesapplymap()
用于 DataFrame,对每个元素应用函数
性能考虑
map()
通常比apply()
更快,因为它专门为 Series 优化- 对于简单的值映射,使用字典的
map()
操作非常高效 - 对于复杂转换,可能需要使用
apply()
特点
- 对于简单的值映射,优先使用字典 +
map()
- 对于元素级转换,使用
map()
配合 lambda 函数或命名函数 - 处理缺失值时,考虑使用
na_action
参数 - 当需要基于多个列进行计算时,使用
apply()
而不是map()
map()
方法是 Pandas 中非常高效和实用的工具,特别适合进行值映射和简单的元素级转换。通过合理使用,可以大大提高数据清洗和转换的效率。