Python中根据N值映射获取第N个唯一值并生成新DataFrame
解决pandas中基于唯一值位置替换DataFrame数值的索引匹配错误
我来帮你解决这个问题,先理清楚你的场景和问题:
你有两个pandas DataFrame:
df1(数值代表df2中ID列的第N个唯一值的位置)
Out 1 Out 2 Out 3 Out 4 Out 5 0 3 1 2 4 5 1 100 50 200 300 200
df2
ID ID2 0 999 888 1 101 801 2 777 666 3 777 666 4 555 100 5 555 100 6 111 100
你的需求是生成df3:将df1中每行的有效位置数值(即不超过df2ID唯一值数量的数值)替换为对应的唯一值,超出范围的数值保持原样,目标结果如下:
Out 1 Out 2 Out 3 Out 4 Out 5 0 777 999 101 555 111 1 100 50 200 300 200
你尝试了@Wen的解决方案后遇到了错误:
ValueError: Row labels must have same size as column labels
这个错误确实和索引/维度对齐有关,下面是可行的解决步骤:
分步解决方案
1. 提取df2中ID列的唯一值列表
首先我们先拿到df2里ID的所有唯一值,这里的顺序就是你需要的“第N个”顺序:
unique_ids = df2['ID'].unique().tolist() # 结果为: [999, 101, 777, 555, 111]
2. 构建位置到唯一值的映射字典
因为df1里的数值是从1开始计数的第N个,而Python列表是0索引,所以我们要创建一个键为“位置序号(1-based)”、值为对应唯一值的字典:
pos_id_map = {idx + 1: val for idx, val in enumerate(unique_ids)} # 结果为: {1:999, 2:101, 3:777, 4:555, 5:111}
3. 对df1进行逐元素替换
使用applymap遍历df1的每个元素,用dict.get()方法来匹配替换:如果元素在映射字典的键中,就替换为对应的唯一值;否则保持原数值不变,这样就不会出现维度对齐的问题了:
df3 = df1.applymap(lambda x: pos_id_map.get(x, x))
执行完这段代码后,你就能得到想要的df3了。
错误原因分析
你之前遇到的ValueError大概率是因为直接尝试用df1的数值去索引unique_ids数组时,df1中存在超出数组长度的数值(比如第二行的100、50等),导致索引操作时维度不匹配;或者是处理过程中没有考虑到df1的索引和唯一值数组的索引对齐问题。而applymap结合get方法是逐元素处理,完美避开了维度对齐的坑。
内容的提问来源于stack exchange,提问作者C_psy
相关产品推荐
相关产品推荐

