How to select the best pair from the ordered dictionary?

Viewed 80

I am trying to map a string to its most suitable match string. I have a confidence score associated with each mapping. I ordered the mappings to get a good sense of how many duplicated mappings of match_string can be observed. The ordered dict is below:

OrderedDict([(('access', 0.9997727), 'アクセス'),
             (('address', 0.44976854), 'お問い合せ先'),
             (('address', 0.99939954), '会社所在地'),
             (('address', 0.99950135), '勤務地'),
             (('app_condition', 0.33275154), '祝'),
             (('app_condition', 0.7852746), '勤務期間'),
             (('app_condition', 0.8870019), '社員登用実績多数'),
             (('app_condition', 0.9899178), '資格・スキル'),
             (('cname', 0.9822838), '会社名'),
             (('companydescr', 0.44985813), '経度'),
             (('feature', 0.69835746), '待遇・福利厚生'),
             (('feature', 0.8646633), 'メリット'),
             (('feature', 0.9998708), '特徴'),
             (('hiretype', 0.9998646), '雇用形態_職種ヒント'),
             (('jd', 0.42525598), '応募方法'),
             (('jd', 0.5210456), '生活スタイルに合わせて働けます'),
             (('jd', 0.7155549), '応募後のプロセス'),
             (('jd', 0.99901605), '仕事内容'),
             (('occup', 0.6487035), '事業内容'),
             (('occup', 0.91239053), '休日・休暇'),
             (('occup', 0.94584364), 'トップ'),
             (('occup', 0.96194524), '掲載URL'),
             (('occup', 0.9865232), 'CMS分類職種'),
             (('salary', 0.69874144), '緯度'),
             (('salary', 0.9436217), '取得日'),
             (('salary', 0.97082114), '交通費'),
             (('salary', 0.9999827), '給与'),
             (('title', 0.999959), 'タイトル'),
             (('workhours', 0.99996305), '勤務曜日・時間'),
             (('workhours', 0.9999968), '時間帯'),
             (('workhours', 0.9999995), '勤務時間')])

I want to select the best match based on confidence scores out of these multiple mappings and create a new dictionary like:

{
'access':'アクセス'
'address':'勤務地'
.
.
.
'workhours':'勤務時間'
}

How can I achieve this? the key of the ordered dict is a tuple, the value is a string.

4 Answers

If your dictionary is already sorted on the confidence score you can just use a dict comprehension:

d = OrderedDict([(('access', 0.9997727), 'アクセス'),
             (('address', 0.44976854), 'お問い合せ先'),
             (('address', 0.99939954), '会社所在地'),
             (('address', 0.99950135), '勤務地'),
...
])
result = {
    key[0]: val for key, val in d.items()
}
print(result)

This is equivalent to:

result = {
   'access': 'アクセス',
   'address': 'お問い合せ先',
   'address': '会社所在地',
   'address': '勤務地',
   ...
}

Since the dictionary is sorted you'll keep only the last value which is the one with best score. So in the end it's like doing:

result = {
   'access': 'アクセス',
   #'address': 'お問い合せ先',
   #'address': '会社所在地',
   'address': '勤務地',
   ...
}

which gives you what you want.

simplest solution would be -

import pandas as pd
from collections import OrderedDict


d = OrderedDict([(('access', 0.9997727), 'アクセス'),
             (('address', 0.44976854), 'お問い合せ先'),
             (('address', 0.99939954), '会社所在地'),
             (('address', 0.99950135), '勤務地'),
             (('app_condition', 0.33275154), '祝'),
             (('app_condition', 0.7852746), '勤務期間'),
             (('app_condition', 0.8870019), '社員登用実績多数'),
             (('app_condition', 0.9899178), '資格・スキル'),
             (('cname', 0.9822838), '会社名'),
             (('companydescr', 0.44985813), '経度'),
             (('feature', 0.69835746), '待遇・福利厚生'),
             (('feature', 0.8646633), 'メリット'),
             (('feature', 0.9998708), '特徴'),
             (('hiretype', 0.9998646), '雇用形態_職種ヒント'),
             (('jd', 0.42525598), '応募方法'),
             (('jd', 0.5210456), '生活スタイルに合わせて働けます'),
             (('jd', 0.7155549), '応募後のプロセス'),
             (('jd', 0.99901605), '仕事内容'),
             (('occup', 0.6487035), '事業内容'),
             (('occup', 0.91239053), '休日・休暇'),
             (('occup', 0.94584364), 'トップ'),
             (('occup', 0.96194524), '掲載URL'),
             (('occup', 0.9865232), 'CMS分類職種'),
             (('salary', 0.69874144), '緯度'),
             (('salary', 0.9436217), '取得日'),
             (('salary', 0.97082114), '交通費'),
             (('salary', 0.9999827), '給与'),
             (('title', 0.999959), 'タイトル'),
             (('workhours', 0.99996305), '勤務曜日・時間'),
             (('workhours', 0.9999968), '時間帯'),
             (('workhours', 0.9999995), '勤務時間')])

df = pd.concat((pd.DataFrame(d.keys()) , pd.DataFrame(d.values())), axis =1 )
df.columns = [0,1,2]     
((df.groupby(0).max())[2]).to_dict()

Output -

{'access': 'アクセス',
 'address': '勤務地',
 'app_condition': '資格・スキル',
 'cname': '会社名',
 'companydescr': '経度',
 'feature': '特徴',
 'hiretype': '雇用形態_職種ヒント',
 'jd': '生活スタイルに合わせて働けます',
 'occup': '掲載URL',
 'salary': '緯度',
 'title': 'タイトル',
 'workhours': '時間帯'}

You can try this:

best_vals = dict()
item_list = list()

i = 0
for key, val in ord_dict.items():
    item_list.append(key[0])
    if key[0] == item_list[i]:
        if len(item_list) == 1:
          best_vals[key[0]] = val
        continue
    else:
        best_vals[key[0]] = val

Output of best_vals:

{'access': 'アクセス',
 'address': '勤務地',
 'app_condition': '資格・スキル',
 'cname': '会社名',
 'companydescr': '経度',
 'feature': '特徴',
 'hiretype': '雇用形態_職種ヒント',
 'jd': '仕事内容',
 'occup': 'CMS分類職種',
 'salary': '給与',
 'title': 'タイトル',
 'workhours': '勤務時間'}

Because your dictionary is sorted in reverse, what i do is check if the current item is the last in your dict and, if it is, I set the value of the corrisponding key.

from collections import OrderedDict


d = OrderedDict([(('access', 0.9997727), 'アクセス'),
             (('address', 0.44976854), 'お問い合せ先'),
             (('address', 0.99939954), '会社所在地'),
             (('address', 0.99950135), '勤務地'),
             (('app_condition', 0.33275154), '祝'),
             (('app_condition', 0.7852746), '勤務期間'),
             (('app_condition', 0.8870019), '社員登用実績多数'),
             (('app_condition', 0.9899178), '資格・スキル'),
             (('cname', 0.9822838), '会社名'),
             (('companydescr', 0.44985813), '経度'),
             (('feature', 0.69835746), '待遇・福利厚生'),
             (('feature', 0.8646633), 'メリット'),
             (('feature', 0.9998708), '特徴'),
             (('hiretype', 0.9998646), '雇用形態_職種ヒント'),
             (('jd', 0.42525598), '応募方法'),
             (('jd', 0.5210456), '生活スタイルに合わせて働けます'),
             (('jd', 0.7155549), '応募後のプロセス'),
             (('jd', 0.99901605), '仕事内容'),
             (('occup', 0.6487035), '事業内容'),
             (('occup', 0.91239053), '休日・休暇'),
             (('occup', 0.94584364), 'トップ'),
             (('occup', 0.96194524), '掲載URL'),
             (('occup', 0.9865232), 'CMS分類職種'),
             (('salary', 0.69874144), '緯度'),
             (('salary', 0.9436217), '取得日'),
             (('salary', 0.97082114), '交通費'),
             (('salary', 0.9999827), '給与'),
             (('title', 0.999959), 'タイトル'),
             (('workhours', 0.99996305), '勤務曜日・時間'),
             (('workhours', 0.9999968), '時間帯'),
             (('workhours', 0.9999995), '勤務時間')])

d = sorted(d.items(), key=lambda item: (item[0][0], -item[0][1]))
res = dict()
for item in d:
  if item[0][0] not in res:
    res[item[0][0]] = item[1]
print("\n".join(str(item) for item in res.items()))

The result is

('access', 'アクセス')
('address', '勤務地')
('app_condition', '資格・スキル')
('cname', '会社名')
('companydescr', '経度')
('feature', '特徴')
('hiretype', '雇用形態_職種ヒント')
('jd', '仕事内容')
('occup', 'CMS分類職種')
('salary', '給与')
('title', 'タイトル')
('workhours', '勤務時間')
Related