
本文介绍了如何利用pandas库高效地根据字典映射对dataframe的列进行聚合求和。通过巧妙地结合字典反转、`rename`和`groupby`操作,我们能够将多个源列合并为一个新列,实现数据的高效重构和分析,避免了传统循环的性能开销。
在数据分析和处理中,我们经常需要根据特定的规则将DataFrame中的多列数据进行聚合。一个常见的场景是,我们有一个DataFrame和一本字典,字典的键代表新的列名,值则是一个列表,包含需要聚合(例如求和)的原始DataFrame中的列名。本文将详细介绍如何使用Pandas的内置功能,以一种高效且Pythonic的方式实现这一目标。
假设我们有一个Pandas DataFrame,其中包含多列数值数据。同时,我们还有一个字典,它定义了如何将这些原始列组合成新的聚合列。
import pandas as pd
# 原始DataFrame
df = pd.DataFrame([[4,8,52,7,54],[0,20,2,21,35],[2,33,12,1,87]], columns = ['A', 'B', 'C', 'D', 'E'])
# 定义聚合规则的字典
# 字典的键是新的列名,值是需要求和的原始列名列表
dic = {'x':['A','D'], 'y' : ['E'], 'z':['B','C']}
print("原始DataFrame:")
print(df)
print("\n聚合字典:")
print(dic)原始DataFrame:
A B C D E 0 4 8 52 7 54 1 0 20 2 21 35 2 2 33 12 1 87
聚合字典:
{'x': ['A', 'D'], 'y': ['E'], 'z': ['B', 'C']}我们的目标是生成一个新的DataFrame,其中包含 'x'、'y'、'z' 三列。列 'x' 的值应是原始 'A' 列和 'D' 列的和,列 'y' 是 'E' 列的值,列 'z' 是 'B' 列和 'C' 列的和。
这种方法的核心思想是:首先创建一个反向映射,将原始列名映射到它们所属的新聚合列名;然后使用 df.rename() 将DataFrame的列名临时重命名;最后,利用 groupby() 结合 axis=1 对重命名后的列进行分组求和。
反转字典映射: 我们需要一个映射关系,将原始列名(如 'A', 'D')作为键,将它们对应的新聚合列名(如 'x')作为值。这可以通过字典推导式实现。
d2 = {v:k for k,l in dic.items() for v in l}
print("反转后的字典映射:")
print(d2)输出:
{'A': 'x', 'D': 'x', 'E': 'y', 'B': 'z', 'C': 'z'}现在,d2 字典告诉我们 'A' 应该属于 'x' 组,'D' 也属于 'x' 组,以此类推。
重命名DataFrame列: 使用 df.rename(columns=d2) 方法,Pandas会根据 d2 字典将DataFrame的列名进行重命名。如果 d2 中没有某个原始列名,该列名将保持不变。
df_renamed = df.rename(columns=d2)
print("\n重命名列后的DataFrame:")
print(df_renamed)输出:
x z z x y 0 4 8 52 7 54 1 0 20 2 21 35 2 2 33 12 1 87
可以看到,现在有多个列被命名为 'x' 或 'z',这就是我们进行聚合的基础。
按列分组求和: 接下来,我们使用 groupby(level=0, axis=1).sum() 对重命名后的列进行分组求和。
out1 = df.rename(columns=d2).groupby(level=0, axis=1).sum()
print("\n聚合求和结果 (方法一):")
print(out1)最终输出:
x y z 0 11 54 60 1 21 35 22 2 3 87 45
值得注意的是,在某些较新版本的Pandas中,groupby 方法的 axis=1 参数可能会被弃用或不推荐使用。为了保持代码的兼容性和适应未来的版本,我们可以采用另一种等效的方法:先转置DataFrame,然后对行进行操作,最后再转置回来。
反转字典映射: 与方法一相同,我们首先创建 d2 字典。
d2 = {v:k for k,l in dic.items() for v in l}转置DataFrame: 使用 df.T 将DataFrame进行转置,使原始列名变为行索引。
df_transposed = df.T
print("\n转置后的DataFrame:")
print(df_transposed)输出:
0 1 2 A 4 0 2 B 8 20 33 C 52 2 12 D 7 21 1 E 54 35 87
重命名行索引: 现在,原始列名位于行索引中,我们可以使用 rename(d2) 对行索引进行重命名。
df_renamed_index = df_transposed.rename(d2)
print("\n重命名行索引后的DataFrame:")
print(df_renamed_index)输出:
0 1 2 x 4 0 2 z 8 20 33 z 52 2 12 x 7 21 1 y 54 35 87
按行分组求和: 现在,具有相同新列名的行索引已经相邻,我们可以直接使用 groupby(level=0).sum() 对行进行分组求和。
df_grouped = df_renamed_index.groupby(level=0).sum()
print("\n分组求和后的DataFrame:")
print(df_grouped)输出:
0 1 2 x 11 21 3 y 54 35 87 z 60 22 45
再次转置: 最后,将结果再次转置回来,以获得期望的列聚合形式。
out2 = df_grouped.T
print("\n聚合求和结果 (方法二):")
print(out2)最终输出:
x y z 0 11 54 60 1 21 35 22 2 3 87 45
可以看到,两种方法得到了完全相同的结果。
本文详细介绍了两种使用Pandas高效实现DataFrame列聚合求和的方法,它们都基于一个字典映射来定义聚合规则。第一种方法直接利用 rename 和 groupby(axis=1),简洁明了;第二种方法通过转置DataFrame来规避 groupby(axis=1) 的潜在兼容性问题,在更广泛的Pandas版本中表现稳定。掌握这些技巧将大大提升你在Pandas中进行数据重构和聚合的效率和灵活性。
以上就是基于字典映射实现Pandas DataFrame列的灵活聚合与求和的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号