You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在DataFrame中将重复字符串与字典值正确关联匹配?

问题解决:DataFrame多层索引中重复字符串与数字的顺序映射

问题背景

在将数字列表与字符串列表关联到多层索引的Pandas Series时,因字符串列表存在重复值,导致重复的字符串总是匹配到最后一个对应数字,无法实现第一个重复字符串对应第一个数字、第二个对应第二个数字的需求。

原代码

import pandas as pd
categories = {"key1":["string1", "string2", "string3"], "key2": ["string1", "str1", "str2"]}
strings= ["string1", "string2", "string3", "string1", "str1", "str2"]
numbers = [1,2,3,4,5,6]

array = []
expected_fields = []

#创建具有双层行索引的DataFrame,第一层为categories的键,第二层为其值列表中的元素
for key, value in categories.items():
    array.extend([key]* len(value))
    expected_fields.extend(value)
    
arrays = [array ,expected_fields]

#创建DataFrame
tuples = list(zip(*arrays))
index = pd.MultiIndex.from_tuples(tuples)
df =  pd.Series(dtype='float', index=index)

for key, values in categories.items():
    for value in values:
        for i in range(len(strings)):
            if strings[i] == value:
                df[key, value] = numbers[i] 
print(df)

当前输出

key1  string1    4.0   <--------- 
      string2    2.0
      string3    3.0
key2  string1    4.0
      str1       5.0
      str2       6.0

期望输出

key1  string1    1.0   <---------
      string2    2.0
      string3    3.0
key2  string1    4.0
      str1       5.0
      str2       6.0

解决方案

核心思路

原循环的问题是每次匹配到相同字符串时都会覆盖之前的值,最后保留的是最后一次匹配的数字。要实现按顺序匹配,需要跟踪每个字符串已匹配的次数,每次匹配时只取未被使用过的对应数字。

修改后的代码

import pandas as pd
categories = {"key1":["string1", "string2", "string3"], "key2": ["string1", "str1", "str2"]}
strings= ["string1", "string2", "string3", "string1", "str1", "str2"]
numbers = [1,2,3,4,5,6]

# 先创建字符串到对应数字的映射,按出现顺序记录每个字符串的数字列表
str_num_map = {}
for s, n in zip(strings, numbers):
    if s not in str_num_map:
        str_num_map[s] = []
    str_num_map[s].append(n)

# 创建多层索引的Series
array = []
expected_fields = []
for key, value in categories.items():
    array.extend([key]* len(value))
    expected_fields.extend(value)

tuples = list(zip(array, expected_fields))
index = pd.MultiIndex.from_tuples(tuples)
df = pd.Series(dtype='float', index=index)

# 遍历categories,按顺序取出对应数字
for key, values in categories.items():
    for value in values:
        # 取出当前字符串的第一个数字,并从列表中移除,确保下一次取的是下一个
        df[key, value] = str_num_map[value].pop(0)

print(df)

代码说明

  1. 首先通过zip(strings, numbers)遍历,为每个字符串创建一个数字列表,按顺序存储所有对应数字。比如string1对应的列表就是[1,4]。
  2. 在填充Series时,每次取出对应字符串列表的第一个数字,然后用pop(0)移除该数字,这样后续再次遇到该字符串时,就会取下一个未使用的数字。
  3. 这个方法不需要统计categories各键的元素数量,完全基于字符串的出现顺序来匹配数字,符合需求。

内容的提问来源于stack exchange,提问作者saul santos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 16:55:19