3
votes

Attribuer un int à des chaînes dans une colonne de listes dans pandas

J'ai un dataframe Pandas qui contient une colonne avec des listes de chaînes.

>>> df.head()

   genre
0  [1,  2,  3]
1  [1,  4,  3]
2  [1]
3  [1,  5,  3,  6]
4  [1,  5,  3]

Comment pourrais-je attribuer à chacune des valeurs de la liste un identifiant unique qui serait le même dans la colonne?

>>> df.head()

   genre
0  [Comedy,  Supernatural,  Romance]
1  [Comedy,  Parody,  Romance]
2  [Comedy]
3  [Comedy,  Drama,  Romance,  Fantasy]
4  [Comedy,  Drama,  Romance]


0 commentaires

3 Réponses :


3
votes

La complication ici est que nous avons affaire à une colonne de listes. Nous pouvons améliorer un peu les performances en éclatant d'abord les lignes. Ensuite, utilisez factorize et revenez au format d'origine:

v = df['genre'].explode()
v[:] = pd.factorize(v)[0] + 1
df['genre2'] = v.groupby(level=0).agg(list)

df
                               genre        genre2
0    [Comedy, Supernatural, Romance]     [1, 2, 3]
1          [Comedy, Parody, Romance]     [1, 4, 3]
2                           [Comedy]           [1]
3  [Comedy, Drama, Romance, Fantasy]  [1, 5, 3, 6]
4           [Comedy, Drama, Romance]     [1, 5, 3]


0 commentaires

0
votes

Vous pouvez configurer un dictionnaire global pour garder une trace des valeurs et utiliser la valeur dans le dictionnaire si elle existe et incrémenter la plus grande valeur si ce n'est pas le cas:

{'Comedy': 1,
 'Supernatural': 2,
 'Romance': 3,
 'Parody': 4,
 'Drama': 5,
 'Fantasy': 6}

Si j'applique cela au df en utilisant:

                              genre     genre_ids

0    [Comedy, Supernatural, Romance]     [1, 2, 3]
1          [Comedy, Parody, Romance]     [1, 4, 3]
2                           [Comedy]           [1]
3  [Comedy, Drama, Romance, Fantasy]  [1, 5, 3, 6]
4           [Comedy, Drama, Romance]     [1, 5, 3]

Je reçois:

df['genre_ids'] = df['genre'].apply(assignId)

avec ce dictionnaire d :

d = {} # Dictionary to assign numerical ids
maxV = 0 # Max numerical id in the dictionary

def assignId(x):
    lst = []
    global d, maxV
    for item in x:       
        if item in d:
            # Get numerical id from the dictionary.
            lst.append(d.get(item))           
        else:
            # Increment the largest numerical id in the dictionary
            # and add it to the dictionary.
            maxV += 1
            d[item] = maxV
            lst.append(maxV)
    return lst


0 commentaires

2
votes

Obtenez des identifiants uniques par genre dans un dictionnaire:

                               genre      genre_id
0    [Comedy, Supernatural, Romance]     [1, 2, 3]
1          [Comedy, Parody, Romance]     [1, 4, 3]
2                           [Comedy]           [1]
3  [Comedy, Drama, Romance, Fantasy]  [1, 5, 3, 6]
4           [Comedy, Drama, Romance]     [1, 5, 3]

Ensuite, utilisez un tel dictionnaire pour mapper l'identifiant de genre:

df.assign(genre_id = df.genre.apply(lambda x: [dict_genres[genre] for genre in x]))

Production:

uniq_genres = df.genre.explode().unique()
dict_genres = {genre:i+1 for i,genre in enumerate(uniq_genres)}
print(dict_genres)
{'Comedy': 1, 'Supernatural': 2, 'Romance': 3, 'Parody': 4, 'Drama': 5, 'Fantasy': 6}


0 commentaires