Python DataFrame:列表列元素减对应行均值的代码问题排查
问题描述
我有一个Pandas DataFrame,其中A列存储数字列表,avg列为A列对应行列表的平均值。我需要创建第三列a_avg,将A列每行列表中的每个元素减去对应行的均值。
我编写的代码如下:
import pandas as pd import numpy as np df = pd.DataFrame({'A':[[4.2,2.3,6.5,2.3],[4.1,5.3,6.5,3.8]]}) df['avg'] = df['A'].apply(lambda p: np.average(p)) df['a_avg'] = df['A'].apply(lambda p: (np.array(p)-df['avg']).to_list())
预期输出为:
A avg a_avg 0 [4.2, 2.3, 6.5, 2.3] 3.825 [0.375, -1.525, 2.675, -1.525] 1 [4.1, 5.3, 6.5, 3.8] 4.925 [-0.825, 0.375, 1.575, -1.125]
我创建avg列是为了便于理解,若能直接从A列生成目标列也可,请问我的代码存在什么问题?
问题分析与解决
你的代码核心问题是:在生成a_avg列的applylambda函数里,df['avg']是整个列的Series对象,而非当前行对应的单个均值。这会导致每个列表的元素都减去整个avg列的所有值,最终得到的是二维数组转成的嵌套列表,完全不符合预期。
方案一:保留avg列的修正代码
通过指定apply的axis=1参数,让lambda函数处理整行数据,这样就能获取当前行的avg值进行计算:
import pandas as pd import numpy as np df = pd.DataFrame({'A':[[4.2,2.3,6.5,2.3],[4.1,5.3,6.5,3.8]]}) df['avg'] = df['A'].apply(lambda p: np.average(p)) # axis=1表示按行处理,row代表当前行数据 df['a_avg'] = df.apply(lambda row: (np.array(row['A']) - row['avg']).tolist(), axis=1)
方案二:直接生成目标列(无需avg列)
如果不需要保留avg列,可以在一次apply中完成均值计算和元素减法,更简洁:
import pandas as pd import numpy as np df = pd.DataFrame({'A':[[4.2,2.3,6.5,2.3],[4.1,5.3,6.5,3.8]]}) df['a_avg'] = df['A'].apply(lambda lst: (np.array(lst) - np.average(lst)).tolist())
运行以上任意一种方案,都能得到你预期的输出结果。
内容的提问来源于stack exchange,提问作者S N B
相关产品推荐
相关产品推荐

