Python Pandas:为现有DataFrame添加字典类型列的技术问题
问题解决与实现方案
给定数据与需求
现有DataFrame df:
index name val 0 Abc 17.29 1 Bcd 137.036 2 Cde 666
需添加列ColDict,每个单元格为字典:键是list_b=[5,7.6,10,20]中元素的字符串形式,值是自定义函数myfunc(x, b)的逐行计算结果(myfunc功能为将x向下取整到不大于x的最大b的倍数)。
先明确自定义函数
def myfunc(x, b): # 向下取整到不大于x的最大b的倍数 return b * (x // b)
针对三个问题的逐一解决
1. 二元函数的逐元素应用
不用纠结map/apply的单变量限制,直接用df.apply()按行处理,或用列表推导式生成字典,两种方式都能规范实现逐元素计算:
- 用
apply时指定axis=1,每一行的val作为x,遍历list_b生成字典; - 列表推导式直接遍历
df["val"]的每个元素,配对list_b生成字典。
2. 避免“切片副本上设置值”警告
标准解决方法:
- 不要直接修改切片后的DataFrame,操作原DataFrame;
- 优先使用
df.assign()方法,该方法返回新的DataFrame,完全避免此类警告,代码更安全规范。
3. 字典作为单元格值的可行性
Pandas完全支持字典作为单元格值,出现“长度不匹配”是因为误将Series/列表赋值给单元格,只要确保每个单元格是单个字典对象即可。如果需要改为多列存储,也可通过循环或字典推导式批量生成。
具体实现代码
方案一:添加字典列ColDict
用assign配合apply实现,无警告且规范:
list_b = [5, 7.6, 10, 20] df = df.assign( ColDict=df["val"].apply( lambda x: {str(b): myfunc(x, b) for b in list_b} ) )
执行后ColDict列内容示例:
- 第0行:
{'5': 15.0, '7.6': 15.2, '10': 10.0, '20': 0.0} - 第1行:
{'5': 135.0, '7.6': 132.8, '10': 130.0, '20': 120.0} - 第2行:
{'5': 665.0, '7.6': 661.2, '10': 660.0, '20': 660.0}
方案二:添加多列(列名格式ColDict_[b])
用字典推导式批量生成列,同样用assign避免警告:
list_b = [5, 7.6, 10, 20] # 生成列名到计算结果的映射 cols_dict = { f"ColDict_{b}": df["val"].apply(lambda x: myfunc(x, b)) for b in list_b } # 批量添加列 df = df.assign(**cols_dict)
执行后会新增ColDict_5、ColDict_7.6、ColDict_10、ColDict_20四列,每列对应对应b值的计算结果。
内容的提问来源于stack exchange,提问作者Hyperi
相关产品推荐
相关产品推荐

