【pandas】-4- 索新增列,assign,applay,map使用

【pandas】-1-读取数据
【pandas】-2-数据查询
【pandas】-3-Pandas 索引

4. Pandas 索新增列,assign,applay,map使用

在 Pandas 中,有多种方式可以新增数据列。我将展示最常用的几种方法,并通过一个示例演示它们的应用。

常用新增列方法

  1. 直接赋值 - 最常用的方式
  2. 使用 assign() 方法 - 函数式编程风格,返回新 DataFrame
  3. 使用 apply() 方法 - 基于函数计算新列
  4. 使用 insert() 方法 - 在指定位置插入列
  5. 使用条件逻辑 - 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'")

最常用的方法

在实际工作中,最常用的新增列方法是:

  1. 直接赋值 - 简单直观,适用于大多数场景
  2. assign()方法 - 适合函数式编程和链式操作
  3. 条件逻辑(np.where) - 用于基于条件的列创建

直接赋值是最简单高效的方式,适用于大多数情况。assign()方法在需要保持原DataFrame不变或进行链式操作时非常有用。条件逻辑则常用于数据分箱和分类变量的创建。

你可以运行上述代码查看各种方法的效果,并根据自己的需求选择最适合的方式。

assign

主要特点

  1. 不修改原 DataFrame:返回一个新的 DataFrame
  2. 支持链式操作 :可以连续调用多个 assign()
  3. 支持 lambda 函数:可以使用 lambda 表达式引用其他列

优点与适用场景

  1. 函数式编程:适合在数据处理的管道操作中使用
  2. 代码可读性:链式操作使代码更加清晰
  3. 不修改原数据:避免意外修改原始数据

注意事项

  1. assign() 返回的是新 DataFrame,原始 DataFrame 不会被修改
  2. 如果需要在原 DataFrame 上修改,需要将结果赋值回原变量
  3. 在同一 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()

与相关方法的比较

  1. apply() vs map() :
    • apply() 可以用于 DataFrame 和 Series
    • map() 只能用于 Series,对每个元素应用函数
  2. apply() vs applymap() :
    • apply() 沿着轴应用函数
    • applymap() 对 DataFrame 的每个元素应用函数
  3. apply() vs transform() :
    • apply() 可以返回聚合结果或转换后的数据
    • transform() 总是返回与原始数据相同形状的结果

特点:

  1. 尽量使用 Pandas 的内置向量化操作,它们通常比 apply() 更快
  2. 当需要复杂逻辑时,使用 apply() 配合自定义函数
  3. 对于简单的元素级操作,考虑使用 map() 或向量化操作
  4. 使用 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)

与相关方法的比较

  1. map() vs apply() :
    • map() 只能用于 Series,对每个元素应用函数或映射
    • apply() 可以用于 DataFrame 和 Series,功能更强大
  2. map() vs replace() :
    • map() 主要用于值转换和映射
    • replace() 主要用于值替换,支持更复杂的替换模式
  3. map() vs applymap() :
    • map() 用于 Series
    • applymap() 用于 DataFrame,对每个元素应用函数

性能考虑

  • map() 通常比 apply() 更快,因为它专门为 Series 优化
  • 对于简单的值映射,使用字典的 map() 操作非常高效
  • 对于复杂转换,可能需要使用 apply()

特点

  1. 对于简单的值映射,优先使用字典 + map()
  2. 对于元素级转换,使用 map() 配合 lambda 函数或命名函数
  3. 处理缺失值时,考虑使用 na_action 参数
  4. 当需要基于多个列进行计算时,使用 apply() 而不是 map()

map() 方法是 Pandas 中非常高效和实用的工具,特别适合进行值映射和简单的元素级转换。通过合理使用,可以大大提高数据清洗和转换的效率。

相关推荐
折翼的恶魔17 小时前
数据分析:排序
python·数据分析·pandas
万粉变现经纪人1 天前
如何解决pip安装报错ModuleNotFoundError: No module named ‘cuml’问题
python·scrapy·beautifulsoup·pandas·ai编程·pip·scipy
折翼的恶魔1 天前
数据分析:合并二
python·数据分析·pandas
☼←安于亥时→❦1 天前
数据分析之Pandas入门小结
python·pandas
TwoAI2 天前
Pandas 数据分析:从入门到精通的数据处理核心
数据挖掘·数据分析·pandas
万粉变现经纪人3 天前
如何解决pip安装报错ModuleNotFoundError: No module named ‘sympy’问题
python·beautifulsoup·pandas·scikit-learn·pyqt·pip·scipy
折翼的恶魔4 天前
数据分析:合并
python·数据分析·pandas
悟乙己4 天前
PySpark 与 Pandas 的较量:Databricks 中 SQL Server 到 Snowflake 的数据迁移之旅
数据库·pandas·pyspark
九章云极AladdinEdu4 天前
临床数据挖掘与分析:利用GPU加速Pandas和Scikit-learn处理大规模数据集
人工智能·pytorch·数据挖掘·pandas·scikit-learn·paddlepaddle·gpu算力