如何使用map函数通过含嵌套列表的字典为DataFrame映射新列
问题原因
df.ID.map(d)会直接将每个ID值映射为字典中对应的完整列表,不会自动按ID的出现顺序逐个取列表内的元素,因此会得到每行存储完整列表的结果。
解决方案
你可以借助groupby分组+transform实现需求,该方案无需额外生成中间列,写法更简洁,前提是每个ID的出现次数和字典中对应列表的长度完全匹配(你的场景刚好符合该条件):
import pandas as pd # 构造示例DataFrame df = pd.DataFrame({'ID': [123,123,123,123,123,123,456,456,456,123]}) d = {'123': [1, 2, 3, 1, 2, 1, 5], '456': [1, 2, 1]} # 先将ID转为字符串,和字典的键类型匹配 df['ID'] = df['ID'].astype(str) # 分组后直接映射列表,transform会自动将列表拆分为每行的单个值 df['Count'] = df.groupby('ID')['ID'].transform(lambda g: d[g.iloc[0]])
运行后输出的df和你期望的结果完全一致:
ID Count 0 123 1 1 123 2 2 123 3 3 123 1 4 123 2 5 123 1 6 456 1 7 456 2 8 456 1 9 123 5
备选方案(适用更广泛场景)
如果存在ID出现次数和列表长度不匹配,仅需要按出现顺序依次取值的场景,可以先计算每个ID的出现次序,再对应取列表元素:
# 计算每个ID在组内的出现序号(从0开始计数) df['idx'] = df.groupby('ID').cumcount() # 按序号取对应列表的元素 df['Count'] = df.apply(lambda x: d[x['ID']][x['idx']], axis=1) # 删除中间生成的idx列 df = df.drop('idx', axis=1)
内容的提问来源于stack exchange,提问作者user16386186
相关产品推荐
相关产品推荐

