Pandas使用assign+Lambda提取字典列表最小值报错求助
Pandas 单列字典列表求每行最小值报错解决方法
问题场景
我有一个单列存储字典列表的DataFrame,每行的列表长度不同,示例数据如下:
import pandas as pd df = pd.DataFrame( [ [[{'value': 1}, {'value': 2}, {'value': 3}]], [[{'value': 4}, {'value': 5}]] ], columns=['data'], )
输出的DataFrame如下:
data 0 [{'value': 1}, {'value': 2}, {'value': 3}] 1 [{'value': 4}, {'value': 5}]
我想新增min_val列存储每行的最小值,尝试用以下代码:
df.assign(min_val=lambda row: min(val['value'] for val in row.data))
但触发了错误:
TypeError: list indices must be integers or slices, not str
类似的Lambda+列表推导式在Dask Bag里能正常运行,但在原生Pandas里报错,求解决方法。
错误原因
df.assign()里的lambda参数不是单行数据,而是整个DataFrame对象。你写的row.data实际是取整个data列的Series,而非每行的列表,所以遍历的时候会出现索引类型不匹配的错误。
正确解法
需要对每行的data列元素单独处理,用Series.apply()来逐行操作:
df['min_val'] = df['data'].apply(lambda lst: min(d['value'] for d in lst))
或者结合assign()使用:
df = df.assign(min_val=df['data'].apply(lambda lst: min(d['value'] for d in lst)))
执行后得到的结果:
data min_val 0 [{'value': 1}, {'value': 2}, {'value': 3}] 1 1 [{'value': 4}, {'value': 5}] 4
补充说明
如果存在空列表的情况,为避免报错可以添加空值判断:
df['min_val'] = df['data'].apply(lambda lst: min(d['value'] for d in lst) if lst else None)
内容的提问来源于stack exchange,提问作者John Duffy
相关产品推荐
相关产品推荐

