Pandas列存列表时的数据类型问题及逐行标准差计算方法
问题解答
列 dtype 为 object 的原因
pandas 中只有单元格存储原生标量值(数值、字符串、时间戳等)时,才会推断为对应类型的 dtype。你虽然将列表内的元素转换为了 float,但每个单元格存储的本体是 Python 列表对象,不属于 pandas 支持的原生标量类型,因此整列 dtype 必然为object。这是正常表现,不影响后续计算,无需额外修复。
逐单元格计算列表标准差
方法1:直接映射计算(适合小数据集)
使用 numpy 的标准差函数逐元素处理单元格内的列表即可:
import numpy as np # ddof=1 计算样本标准差,若需总体标准差设置 ddof=0 df_final['old_std'] = df_final['df_old_obj'].apply(lambda lst: np.std(lst, ddof=1)) df_final['curr_std'] = df_final['df_curr_obj'].apply(lambda lst: np.std(lst, ddof=1))
针对给出的示例数据,_rev行df_old_obj列的[79.5, 0.25]计算得到样本标准差约为56.04,df_curr_obj列的[92.0, 0.5]计算得到样本标准差约为64.70;单元素列表的标准差返回0,符合计算逻辑。
方法2:拆分列表为多列后计算(推荐,性能更优)
将列表存在单个单元格属于非结构化存储,数据量较大时apply循环性能很差。更优的方式是先将列表拆分为独立的数值列,再用 pandas 原生的行级计算方法求标准差:
# 拆分列表为多列,长度不足的列表自动填充NaN,保留原行索引 old_split = pd.DataFrame(df_final['df_old_obj'].tolist(), index=df_final.index).add_prefix('old_top') curr_split = pd.DataFrame(df_final['df_curr_obj'].tolist(), index=df_final.index).add_prefix('curr_top') # 拆分后的列拼回原表 df_final = pd.concat([df_final, old_split, curr_split], axis=1) # 原生行级计算,性能远高于apply循环 df_final['old_std'] = old_split.std(axis=1, ddof=1) df_final['curr_std'] = curr_split.std(axis=1, ddof=1)
拆分后的值列均为原生 float 类型,后续做均值、极值、分位数等聚合计算时无需额外处理列表,维护成本更低。
内容的提问来源于stack exchange,提问作者Ray92
相关产品推荐
相关产品推荐

