
本教程详细介绍了在pandas dataframe中对多列执行批量加减运算的两种高效方法。我们将探讨如何利用`dataframe.eval()`进行多行表达式求值,以及如何通过链式调用`add()`和`sub()`方法结合向量化操作实现相同效果。文章将提供详细的代码示例和解释,帮助读者根据具体场景选择最合适的策略,从而提升数据处理效率和代码可读性。
在数据分析和处理中,我们经常需要对Pandas DataFrame中的多个列执行相同的算术运算。例如,可能需要将某个基准列的值从一组目标列中减去,然后再加上另一个参考列的值。手动逐列编写这样的操作(如 df['C'] = df['C'] - df['B'] + df['A'],然后对 D 和 E 重复)不仅冗长,而且效率低下,尤其当涉及的列数很多时。本教程将介绍两种更优雅、更高效的解决方案,帮助您简化代码并提升性能。
DataFrame.eval() 方法允许您使用字符串表达式对DataFrame进行计算,其语法更接近数学表达式,并且可以处理多行表达式,从而实现对多列的批量操作。对于复杂的、涉及多个列的运算,eval() 提供了一种简洁且可读性强的解决方案。
假设我们有一个DataFrame df,需要将列 C, D, E 分别减去 B 列的值,然后加上 A 列的值。
import pandas as pd
data = {
"A": [42, 38, 39, 23],
"B": [45, 30, 15, 65],
"C": [60, 50, 25, 43],
"D": [12, 70, 35, 76],
"E": [87, 90, 45, 43],
"F": [40, 48, 55, 76],
"G": [58, 42, 85, 10],
}
df = pd.DataFrame(data)
print("原始DataFrame:")
print(df)
# 使用eval()进行批量操作
df_eval = df.copy() # 创建副本以避免修改原始DataFrame
df_eval = df_eval.eval('''C = C - B + A
D = D - B + A
E = E - B + A
''')
print("\n使用eval()后的DataFrame:")
print(df_eval)eval() 方法接受一个多行字符串作为参数,其中每一行代表一个赋值表达式。在表达式中,您可以直接引用DataFrame的列名,eval() 会自动识别并将其视为Series对象进行计算。这种方法在内部利用NumExpr库进行优化,对于大型数据集可以提供显著的性能提升。它将多个独立的赋值操作合并为一个高效的内部计算过程。
Pandas的Series和DataFrame对象支持向量化操作,这意味着您可以对整个列或DataFrame执行算术运算,而无需编写显式的循环。通过链式调用 add() 和 sub() 等方法,我们可以构建出高效且表达力强的批量操作。这种方法特别适用于当多个目标列需要应用相同的偏移量或变换时。
我们将使用与上述相同的数据集,通过链式方法实现相同的运算。
import pandas as pd
data = {
"A": [42, 38, 39, 23],
"B": [45, 30, 15, 65],
"C": [60, 50, 25, 43],
"D": [12, 70, 35, 76],
"E": [87, 90, 45, 43],
"F": [40, 48, 55, 76],
"G": [58, 42, 85, 10],
}
df = pd.DataFrame(data)
# print("原始DataFrame:") # 原始DataFrame已在eval示例中打印
# print(df)
# 使用链式add/sub进行批量操作
df_chained = df.copy() # 创建副本以避免修改原始DataFrame
# 计算共同的偏移量:A - B
# df['A'].sub(df['B']) 等同于 df['A'] - df['B']
offset = df_chained['A'].sub(df_chained['B'])
# 将偏移量加到目标列上
# df[['C', 'D', 'E']] 是一个包含目标列的子DataFrame
# .add(offset, axis=0) 将 Series 'offset' 按行(axis=0)广播到子DataFrame的每一列
df_chained[['C', 'D', 'E']] = df_chained[['C', 'D', 'E']].add(offset, axis=0)
print("\n使用链式add/sub后的DataFrame:")
print(df_chained)这种方法的核心在于利用Pandas的广播机制。首先,我们计算出所有目标列都需要共享的共同偏移量 A - B,这会得到一个Series对象 offset。然后,我们选择目标列 df_chained[['C', 'D', 'E']],并使用 .add() 方法将 offset Series 添加到这些列上。axis=0 参数确保 offset Series 的值按行与目标DataFrame的每一列对齐并相加。这种方式非常直观,且充分利用了Pandas底层的优化,提供了出色的性能。
性能考量: 对于大多数常见的数据集大小,这两种方法都比传统的Python循环快得多。在极大规模的数据集上,eval() 可能会因其底层的NumExpr优化而略胜一筹。然而,在实际应用中,选择哪种方法更多取决于代码的可读性、维护性以及个人或团队的偏好。
Pandas为DataFrame中的批量算术运算提供了多种高效且灵活的工具。DataFrame.eval() 提供了一种简洁的字符串表达式方式,适用于复杂的多行逻辑。而链式调用 add() 和 sub() 等方法则通过向量化和广播机制,为重复的、结构化的运算提供了清晰高效的解决方案。掌握这两种方法,将使您能够更有效地处理数据,编写出更简洁、更专业的Pandas代码。在实际工作中,建议根据具体任务的复杂性、代码的可读性要求以及性能需求来选择最适合的方法。
以上就是Pandas DataFrame:优化多列批量加减运算的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号