如何使用 pandas 的apply函数对 DataFrame 的多个列进行操作
参考:pandas apply to multiple columns
在数据分析和数据处理中,pandas 是 Python 中最受欢迎的库之一。pandas 提供了非常强大的数据结构和数据操作工具,使得处理和分析大规模数据变得更加容易和高效。本文将详细介绍如何使用 pandas 的 apply
函数对 DataFrame 的多个列进行操作。
1. pandas apply 函数简介
pandas 的 apply
函数允许用户对 DataFrame 的行或列应用一个函数。这是一个非常强大的功能,因为它可以让我们对数据进行复杂的处理,而不仅仅是简单的数学运算。apply
函数可以用于单列,也可以扩展到多列,本文的重点是后者。
2. 使用 apply 函数处理多列
当我们需要对 DataFrame 中的多个列应用同一个函数时,可以使用 apply
函数。这种情况下,通常会将这些列作为一个整体来处理。
示例代码 1:基本使用
import pandas as pd
# 创建一个示例 DataFrame
data = {'Name': ['Alice', 'Bob', 'Charlie'], 'Age': [25, 30, 35], 'City': ['New York', 'Los Angeles', 'Chicago']}
df = pd.DataFrame(data)
# 定义一个简单的函数,将年龄增加10年
def add_age(x):
return x + 10
# 应用函数到 'Age' 列
df['New Age'] = df['Age'].apply(add_age)
print(df)
Output:
示例代码 2:对多列使用同一函数
import pandas as pd
# 创建一个示例 DataFrame
data = {'First Score': [100, 90, 85], 'Second Score': [80, 85, 90]}
df = pd.DataFrame(data)
# 定义一个函数,计算平均分
def average_score(row):
return (row['First Score'] + row['Second Score']) / 2
# 应用函数到每一行
df['Average Score'] = df.apply(average_score, axis=1)
print(df)
Output:
示例代码 3:使用 lambda 函数
import pandas as pd
# 创建一个示例 DataFrame
data = {'A': [1, 2, 3], 'B': [4, 5, 6]}
df = pd.DataFrame(data)
# 使用 lambda 函数对多列进行求和
df['Sum'] = df.apply(lambda x: x['A'] + x['B'], axis=1)
print(df)
Output:
示例代码 4:结合条件语句
import pandas as pd
# 创建一个示例 DataFrame
data = {'Score': [88, 92, 85], 'Grade': ['B', 'A', 'B']}
df = pd.DataFrame(data)
# 定义一个函数,根据分数调整等级
def adjust_grade(row):
if row['Score'] > 90:
return 'A+'
return row['Grade']
# 应用函数到每一行
df['Adjusted Grade'] = df.apply(adjust_grade, axis=1)
print(df)
Output:
示例代码 5:处理更复杂的数据转换
import pandas as pd
# 创建一个示例 DataFrame
data = {'Price': [95, 85, 75], 'Tax': [0.15, 0.10, 0.20]}
df = pd.DataFrame(data)
# 定义一个函数,计算总价
def total_price(row):
return row['Price'] * (1 + row['Tax'])
# 应用函数到每一行
df['Total Price'] = df.apply(total_price, axis=1)
print(df)
Output:
3. apply 函数的高级用法
apply
函数不仅限于简单的数学运算,它可以结合任何类型的 Python 函数来处理数据,包括统计函数、字符串操作、条件复杂逻辑等。
示例代码 6:使用自定义复杂函数
import pandas as pd
# 创建一个示例 DataFrame
data = {'Name': ['Alice', 'Bob', 'Charlie'], 'Salary': [50000, 60000, 70000]}
df = pd.DataFrame(data)
# 定义一个复杂的函数,根据薪水调整名称显示
def custom_display(row):
return f"{row['Name']} - ${row['Salary']}"
# 应用函数到每一行
df['Display'] = df.apply(custom_display, axis=1)
print(df)
Output:
示例代码 7:结合多个 DataFrame 的操作
import pandas as pd
# 创建两个示例 DataFrame
data1 = {'ID': [1, 2, 3], 'Product': ['Computer', 'Phone', 'Printer']}
df1 = pd.DataFrame(data1)
data2 = {'ID': [1, 2, 3], 'Price': [1200, 300, 150]}
df2 = pd.DataFrame(data2)
# 合并 DataFrame
df_merged = pd.merge(df1, df2, on='ID')
# 定义一个函数,生成产品信息字符串
def product_info(row):
return f"{row['Product']} costs ${row['Price']}"
# 应用函数到合并后的 DataFrame
df_merged['Product Info'] = df_merged.apply(product_info, axis=1)
print(df_merged)
Output:
示例代码 8:利用 apply 进行数据清洗
import pandas as pd
# 创建一个示例 DataFrame
data = {'Date': ['2021-01-01', '2021-02-30', '2021-03-15']}
df = pd.DataFrame(data)
# 定义一个函数,修正不正确的日期
def correct_date(date_str):
if date_str == '2021-02-30':
return '2021-02-28'
return date_str
# 应用函数到 'Date' 列
df['Corrected Date'] = df['Date'].apply(correct_date)
print(df)
Output:
示例代码 9:使用 apply 进行类型转换
import pandas as pd
# 创建一个示例 DataFrame
data = {'Number': ['1', '2', '3']}
df = pd.DataFrame(data)
# 定义一个函数,将字符串转换为整数
def to_int(num_str):
return int(num_str)
# 应用函数到 'Number' 列
df['Integer'] = df['Number'].apply(to_int)
print(df)
Output:
示例代码 10:结合外部数据源
import pandas as pd
# 创建一个示例 DataFrame
data = {'Country Code': ['US', 'CN', 'JP']}
df = pd.DataFrame(data)
# 定义一个函数,根据国家代码获取国家名称
def get_country_name(code):
country_dict = {'US': 'United States', 'CN': 'China', 'JP': 'Japan'}
return country_dict.get(code, 'Unknown')
# 应用函数到 'Country Code' 列
df['Country Name'] = df['Country Code'].apply(get_country_name)
print(df)
Output:
4. apply 函数的性能考虑
虽然 apply
函数非常灵活和强大,但在处理大型数据集时,性能可能成为一个问题。apply
函数通常比 pandas 的内置向量化函数慢,因为它需要在 Python 层面上循环每一行或列。因此,在可能的情况下,推荐使用 pandas 的内置函数,如 sum()
, mean()
等,或者使用向量化操作来提高性能。
示例代码 11:向量化操作替代 apply
import pandas as pd
# 创建一个示例 DataFrame
data = {'A': [10, 20, 30], 'B': [20, 30, 40]}
df = pd.DataFrame(data)
# 使用向量化操作进行列相加,替代 apply
df['Sum'] = df['A'] + df['B']
print(df)
Output:
示例代码 12:使用内置函数计算平均值
import pandas as pd
# 创建一个示例 DataFrame
data = {'Scores': [88, 92, 85, 78, 90]}
df = pd.DataFrame(data)
# 使用内置函数计算平均分,替代 apply
average_score = df['Scores'].mean()
print("Average Score:", average_score)
Output:
6. apply 函数与其他 pandas 函数的结合使用
apply
函数可以与 pandas 的其他函数结合使用,以实现更复杂的数据处理流程。例如,可以结合使用 groupby
和 apply
来对分组数据进行复杂的自定义操作。
示例代码 13:结合 groupby 和 apply
import pandas as pd
# 创建一个示例 DataFrame
data = {'Department': ['Sales', 'Sales', 'HR', 'HR'], 'Employee': ['Alice', 'Bob', 'Charlie', 'David'], 'Sales': [200, 150, None, None]}
df = pd.DataFrame(data)
# 使用 groupby 和 apply 计算每个部门的平均销售额
def average_sales(x):
return x.dropna().mean()
average_sales_per_dept = df.groupby('Department')['Sales'].apply(average_sales)
print(average_sales_per_dept)
Output:
示例代码 14:apply 结合条件过滤
import pandas as pd
# 创建一个示例 DataFrame
data = {'Product': ['Apple', 'Banana', 'Cherry'], 'Price': [1.2, 0.5, 2.5]}
df = pd.DataFrame(data)
# 定义一个函数,过滤出价格高于1美元的产品
def filter_expensive_products(row):
if row['Price'] > 1:
return row
# 使用 apply 结合条件过滤
expensive_products = df.apply(filter_expensive_products, axis=1).dropna()
print(expensive_products)
Output:
7. apply 函数的错误处理
在使用 apply
函数时,可能会遇到错误或异常。合理的错误处理可以使数据处理流程更加健壮。
示例代码 15:apply 中的错误处理
import pandas as pd
# 创建一个示例 DataFrame
data = {'Number': [10, 20, 'error', 40]}
df = pd.DataFrame(data)
# 定义一个函数,尝试将值转换为整数,错误则返回 None
def safe_convert_to_int(x):
try:
return int(x)
except ValueError:
return None
# 使用 apply 进行安全类型转换
df['Converted'] = df['Number'].apply(safe_convert_to_int)
print(df)
Output:
8. 总结与展望
本文详细介绍了 pandas 的 apply
函数在多列数据处理中的应用,包括基本用法、性能考虑、与其他函数的结合使用以及错误处理等方面。通过多个示例代码,我们展示了 apply
函数的灵活性和强大功能。