2
votes

Comment convertir une liste en un dictionnaire qui utilise tuple comme clé

Je voudrais lire un tableau Excel avec Panda et créer une liste de tuples. Ensuite, je veux convertir la liste en un dictionnaire qui a un tuple comme clé. Comment puis-je faire cela?

Voici le tableau que je lis;

my_data =  {("A", "B"): 0.6,

            ("A", "C"): 0.7,

            ("C", "D"): 1,

            ("C", "A"): 1.2,

            ("D", "B"): 0.7,

            ("D", "C"): 0.6}

Voici comment je lis mon tableau;

import pandas as pd

df= pd.read_csv("my_file_name.csv", header= None)  

my_tuple = [tuple(x) for x in df.values]


1 commentaires

Consultez l'article pertinent de Martjin sur ordre du dictionnaire et pourquoi vous voyez un ordre différent dans Python 3.5


5 Réponses :


1
votes

Jan - voici une idée: créez simplement une colonne clé en utilisant la fonction pandas apply pour générer un tuple de vos 2 premières colonnes, puis compressez-les dans un dict.

import pandas as pd
df = pd.read_clipboard()
df.columns = ['first', 'second', 'value']
df.head()

def create_key(row):
    return (row['first'], row['second'])

df['key'] = df.apply(create_key, axis=1)

dict(zip(df['key'], df['value']))

{('A', 'C'): 0.7,
 ('C', 'A'): 1.2,
 ('C', 'D'): 1.0,
 ('D', 'B'): 0.7,
 ('D', 'C'): 0.6}


0 commentaires

3
votes

Set_index et to_dict

k = df[['A', 'B']].to_records(index=False).tolist()
dict(zip(k, df['C']))

Option2: Une autre solution utilisant zip

dict(zip(df[['A', 'B']].apply(tuple, 1), df['C']))

Option 3:

df.set_index(['a', 'b']).c.to_dict()

{('A', 'B'): 0.6,
 ('A', 'C'): 0.7,
 ('C', 'A'): 1.2,
 ('C', 'D'): 1.0,
 ('D', 'B'): 0.7,
 ('D', 'C'): 0.6}


9 commentaires

Merci d'avoir répondu. J'ai donc mis à jour la façon dont je lis le tableau comme df = pd.read_csv ("my_file_name.csv", header = None, names = ["A", "B", "C"]). Ensuite, j'appelle la fonction suivante print (df.set_index (['A', 'B']). C.to_dict ()). Ma sortie ressemble à {('D', 'C'): 0.6, ('A', 'C'): 0.7, ('D', 'B'): 0.7, ('C', 'A') : 1,2, ('A', 'B'): 0,6, ('C', 'D'): 1,0}. Savez-vous pourquoi la commande est modifiée?


Pouvez-vous mettre à jour votre message avec df.head () après avoir lu vos données avec les noms de colonnes?


J'ai donc ajouté df.head () mais maintenant j'obtiens l'ordre suivant {('C', 'A'): 1.2, ('D', 'B'): 0.7, ('A', 'C') : 0,7, («D», «C»): 0,6, («C», «D»): 1,0, («A», «B»): 0,6}. Quelles sont les lettres minuscules que vous avez utilisées dans votre réponse? Ce sont aussi des noms de colonnes, n'est-ce pas?


@ball_jan quelle version de python utilisez-vous?


a, b et c sont des noms de colonnes. Avec votre code, df.set_index (['A', 'B']). C.to_dict ()


J'utilise Python 3.5. Toutes les méthodes de résolution recommandées ici semblent fonctionner correctement, mais l'ordre change dans tous les cas.


Le dictionnaire Python est intrinsèquement non ordonné. De plus, si vous avez une autre instance des mêmes combinaisons de colonnes, la seconde remplacera la première pour remplacer la valeur


Vaishali, j'apprécie vraiment votre aide et vos réponses. Puis-je utiliser l'index de colonne plutôt que le nom pour effectuer la même opération?


Vous pouvez essayer une autre solution que j'ai publiée. Cela fonctionne par index



1
votes

Ceci est moins concis que la réponse de @ Vaishali mais vous donne davantage une idée des étapes.

vals1 = df['A'].values
vals2 = df['B'].values
vals3 = df['C'].values

dd = {}
for i in range(len(vals1)):
    key = (vals1[i], vals2[i])
    value = vals3[i]
    dd[key] = value

{('A', 'B'): '0.6',
('A', 'C'): '0.7',
('C', 'D'): '1.0',
('C', 'A'): '1.2',
('D', 'B'): '0.7',
('D', 'C'): '0.6'}


0 commentaires

1
votes

Si vous utilisiez un code simple:

celui-ci n'utiliserait aucun élément d'importation tel que panda:

{('A', 'B'): '0.6', ('A', 'C'): '0.7', ('C', 'D'): '1.0', ('C', 'A'): '1.2', ('D', 'B'): '0.7', ('D', 'C'): '0.6'}

donc hors de vous.

et le résultat est:

def change_csv(filename):
    file_pointer = open(filename, 'r')
    data = file_pointer.readlines()
    dict = {}
    file_pointer.close()
    for each_line in data:
        a, b, c =  each_line.strip().split(" ")
        dict[a, b] = c
    return dict


0 commentaires

1
votes

Une compréhension fonctionnera bien pour des cadres plus petits:

from collections import OrderedDict

d = OrderedDict((tuple((a, b)), c) for a,b,c in df.values)
#OrderedDict([(('A', 'B'), 0.6),
#             (('A', 'C'), 0.7),
#             (('C', 'D'), 1.0),
#             (('C', 'A'), 1.2),
#             (('D', 'B'), 0.7),
#             (('D', 'C'), 0.6)])

Si vous rencontrez des problèmes de commande:

dict((tuple((a, b)), c) for a,b,c in df.values)
#{('A', 'B'): 0.6,
# ('A', 'C'): 0.7,
# ('C', 'A'): 1.2,
# ('C', 'D'): 1.0,
# ('D', 'B'): 0.7,
# ('D', 'C'): 0.6}


0 commentaires