如何在Pandas DataFrame各列应用多函数并自定义列名
解决Pandas中生成带自定义列名的衍生列问题
首先咱们先明确你的需求:你有一个简单的DataFrame,想要为每一列生成两个衍生列——分别是该列值与列均值的乘积、该列值与列极差的乘积,并且新列要带对应原列名的描述性名称,最终输出的列顺序也要和你期望的一致。
先看你给出的原始DataFrame代码:
import pandas as pd import numpy as np df0 = pd.DataFrame([[1,2],[3,4],[5,6]], columns=['X','Y'])
你的原代码问题分析
你尝试用.agg方法传入自定义函数,但遇到两个问题:
- 没法传递列名:你的函数里生成的列名是固定的
data、Xa、Xb,没办法对应原列的名称(比如X、Y); - 触发ValueError:这是因为
.agg方法默认期望函数返回标量或者一维的结果(比如Series),但你的函数返回了一个二维的DataFrame,导致Pandas在对齐索引和列的时候出现了匹配错误,所以抛出了这个异常。
解决方案:两种实现方式
方式一:遍历列手动生成衍生列(最直观易控)
这种方式直接遍历每一列,计算所需的均值和极差,然后生成带对应后缀的新列,最后调整列顺序即可:
import pandas as pd import numpy as np df0 = pd.DataFrame([[1,2],[3,4],[5,6]], columns=['X','Y']) # 遍历每一列生成衍生列 for col in df0.columns: col_mean = df0[col].mean() col_range = df0[col].max() - df0[col].min() # 生成带描述性名称的新列 df0[f'{col}_mean'] = df0[col] * col_mean df0[f'{col}_range'] = df0[col] * col_range # 调整列顺序,匹配你期望的输出格式 df0 = df0[['X', 'X_mean', 'X_range', 'Y', 'Y_mean', 'Y_range']] print(df0)
运行后就能得到你想要的输出:
X X_mean X_range Y Y_mean Y_range 0 1 3 4 2 8 8 1 3 9 12 4 16 16 2 5 15 20 6 24 24
方式二:用apply结合Series实现(贴近你想用聚合类方法的需求)
如果你更倾向于用类似聚合的方式处理,可以用.apply方法,在函数中通过data.name拿到当前列的名称,返回包含原列和衍生列的Series,最后整理结构:
import pandas as pd import numpy as np df0 = pd.DataFrame([[1,2],[3,4],[5,6]], columns=['X','Y']) def process_col(data): col_name = data.name col_mean = data.mean() col_range = data.max() - data.min() # 返回包含原列和两个衍生列的Series,索引用带后缀的列名 return pd.Series({ col_name: data, f'{col_name}_mean': data * col_mean, f'{col_name}_range': data * col_range }) # 应用函数并整理结构 result = df0.apply(process_col).unstack().reset_index(drop=True).T # 设置列名和索引 result.columns = ['X', 'X_mean', 'X_range', 'Y', 'Y_mean', 'Y_range'] result.index = [0,1,2] print(result)
这个方式也能得到和方式一完全一样的结果。
问题根源总结
- 关于列名传递:不管是遍历列还是用
apply,都能轻松拿到原列的名称(遍历直接取col,apply中用data.name),这样就能生成带描述性的新列名; - 关于ValueError:避免在
.agg中返回二维的DataFrame,改用直接生成列或者返回一维的Series结构,让Pandas能正确处理数据的对齐逻辑。
内容的提问来源于stack exchange,提问作者user7864386
相关产品推荐
相关产品推荐

