构建一对匹配字符串的唯一标识符字典。

4

我有一个像这样的数据框

#Test dataframe
import pandas as pd
import numpy as np

#Build df

titles = {'Title': ['title1', 'cat', 'dog']}
references = {'References': [['donkey','chicken'],['title1','dog'],['bird','snake']]}

df = pd.DataFrame({'Title': ['title1', 'cat', 'dog'], 'References': [['donkey','chicken'],['title1','dog'],['bird','snake']]})
#Insert IDs for UNIQUE titles
title_ids = {'IDs':list(np.arange(0,len(df)) + 1)}

df['IDs'] = list(np.arange(0,len(df)) + 1)
df = df[['Title','IDs','References']]

enter image description here

我希望为参考列生成类似数据框下方的ID。如果字符串之间存在匹配,则分配与IDs列中相同的ID;如果不存在匹配,则分配新的唯一ID。

enter image description here

我的第一次尝试是使用函数

#Matching function
def string_match(string1,string2):
    if string1 == string2:
        a = 1
    else:
        a = 0

    return a

我希望能够循环遍历每个字符串/标题组合,但是如果使用多个for循环和if语句会变得很棘手。有没有更符合Python风格的方法可以解决这个问题?


你的图片中为什么RefID从4开始? - ML-Nielsen
由于“驴”不在IDs列中,即它是一个新字符串,因此它被分配为max(IDs) + 1,从而赋予它一个唯一的ID。 - keeran_q789
3个回答

2
# Explode to one reference per row
references = df["References"].explode()

# Combine existing titles with new title from References
titles = pd.concat([df["Title"], references]).unique()

# Assign each title an index number
mappings = {t: i + 1 for i, t in enumerate(titles)}

# Map the reference to the index number and convert to list
df["RefIDs"] = references.map(mappings).groupby(level=0).apply(list)

如果我想使用模糊匹配或近似字符串匹配函数来匹配部分更复杂的词,并为它们赋予相同的ID,例如'cat'和'cats',您会建议如何修改这种方法? - keeran_q789
你可以尝试对 mappings 字典进行操作,基于模糊匹配的原理,将 catcats 映射到同一个 ID 上。 - Code Different
你知道怎么简单地完成这个吗? - keeran_q789

1

让我们尝试使用因式分解

s = df['References'].explode()
s[:] = pd.concat([df['Title'],s]).factorize()[0][len(df['Title']):]
df['new'] = (s+1).groupby(level=0).agg(list)
Out[237]: 
0    [4, 5]
1    [1, 3]
2    [6, 7]
Name: References, dtype: object

1

除了答案之外,这也可以通过使用函数applylambda来完成:

id_info=dict(df[['Title','IDs']].values)
def check(title,ref):
    new_id_ = max(id_info.values())  #get latest id

    ids=[]
    for i in ref:
        if i in id_info:  #if Reference value is defined before, get its id
            new_id=id_info[i]
        else:
            new_id=new_id_ + 1 #define a new id if not defined before and update dictionary to get latest id in next steps
            new_id_+=1
            id_info.update({i:new_id})          
        ids.append(new_id)
    return ids
    
df['new_id']=df.apply(lambda x: check(x['Title'],x['References']),axis=1)
print(df)
'''
    Title   IDs References              RefIDs
0   title1  1   ['donkey', 'chicken']   [4, 5]
1   cat     2   ['title1', 'dog']       [1, 3]
2   dog     3   ['bird', 'snake']       [6, 7]


'''

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接