如何实现对多行的动态搜索

How to implement a dynamic search over multiple rows

我有一个 df 看起来与下面类似,但有 100 列,其中每列引用不同的文本分辨率。

Index A/RES/73/262 A/RES/73/263
Issue-Primary ME HR
Issue-Secondary NaN NaN
Description Protection of the Palestinian civilian Situation of human rights in Myanmar

我有一个脚本,它循环遍历每个解决方案描述,并在“Issue-Primary”中为已定义的搜索词词典设置一个值。

df = pd.read_excel("file_name")
issue_dict = {'human rights':'HR', 'Protection':'HR', 'Palestinian':'ME'} 
key_pattern = re.compile(rf'({"|".join(issue_dict.keys())})')

for columnName, columnData in df.iteritems():
    matched_key = re.search(key_pattern, str(columnData[1]))
    if matched_key:
        columnData[0] = issue_dict.get(matched_key.group(), "Issue-Primary")
    else:
        columnData[0] = np.NaN

有些解决方案的描述与多个问题相关,因此我想将类似的脚本应用于我的“问题-次要”行。但是,我需要确保当脚本为“Issue-Secondary”设置值时,它会忽略与“Issue-Primary”中的代码相关的术语

例如,“Protection”与'HR'相关,因此在脚本为“Issue-Primary”中的“ME”设置值后的第一列中,它应该return为“ Issue-Secondary”并应用相同的过程而不查找“ME”术语(否则它只是重复“ME”)。理想情况下,“Issue-Primary”将设置为“ME”,“Issue-Secondary”在第一个解决方案列中设置为“HR”。

以下是我的第一次尝试。但是,如您所想,由于我使用的是相同的 issue_dict,因此它不会产生预期的结果。我不确定在将脚本应用于“Issue-Secondary”时,确保忽略“Issue-Primary”中的任何术语的最佳方法是什么。

issue_codes_list = ['HR', 'ME']
key_pattern = re.compile(rf'({"|".join(issue_dict.keys())})')

for columnName, columnData in df.iteritems():
    matched_key = re.search(key_pattern, str(columnData[1]))
    if matched_key:
        columnData[0] = issue_dict.get(matched_key.group(), "Issue-Primary")
    else:
        columnData[0] = np.NaN
    
    for j in issue_codes_list:
        if columnData[0] == j:
            if matched_key:
                columnData[1] = issue_dict.get(matched_key.group(), "Issue-Secondary")
            else:
                columnData[1] = np.NaN

您可以使用 re.findall 一次查找要匹配的所有字符串,然后只保留唯一值:

df = pd.DataFrame(index=['Issue-Primary','Issue-Secondary','Description'],columns=['a','b'])
df.loc['Description']=['Protection of the Palestinian civilian',
                       'Situation of human rights in Myanmar']

issue_dict = {'human rights':'HR', 'Protection':'HR', 'Palestinian':'ME'} 
key_pattern = re.compile(rf'({"|".join(issue_dict.keys())})')

for columnName, columnData in df.iteritems():
    matched_key = re.findall(key_pattern, str(columnData[2]))
    if matched_key:
        
        all_issues = [issue_dict.get(x, "Issue-Primary") for x in matched_key]
        issues=list()
        for i in all_issues:
            if i not in issues: issues.append(i)
        
        if len(issues)>0:
            columnData[0] = issues[0]
        if len(issues)>1:
            columnData[1] = issues[1]

returns 对于 df:

a b
Issue-Primary HR HR
Issue-Secondary ME NaN
Description Protection of the Palestinian civilian Situation of human rights in Myanmar

不过,我不确定您如何在第一列中获得 'ME' 的 Issue-Primary。如果顺序无关紧要,您可以通过将以 all_issues 开始的块替换为

来节省几行
issues = list(set([issue_dict.get(x, "Issue-Primary") for x in matched_key]))

set() 将删除重复项。

我也不确定你使用 issue_dict.get(matched_key.group(), "Issue-Primary") 而不是 issue_dict[matched_key.group()].

是否有用