【问题标题】:How to implement a dynamic search over multiple rows如何在多行上实现动态搜索
【发布时间】:2022-01-05 17:05:35
【问题描述】:

我有一个类似于下面的 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

我有一个循环遍历每个解决方案描述的脚本,并在“问题主要”中为定义的搜索词词典设置一个值。

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”的值后的第一列,它应该返回“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

【问题讨论】:

    标签: python pandas search


    【解决方案1】:

    您可以使用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]
    

    返回 df:

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

    我不确定您是如何在第一列中为 Issue-Primary 获得“ME”的。如果顺序无关紧要,您可以通过将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()]。

    【讨论】:

    • 谢谢!这很好用。订购并不重要,因此也感谢您提供额外的效率。
    猜你喜欢
    • 2015-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-07
    • 2011-10-19
    • 1970-01-01
    • 1970-01-01
    • 2016-12-29
    相关资源
    最近更新 更多