2017-04-11 2 views
1

Je tente de lire deux fichiers .dat et de créer un programme utilisant la valeur de aid2name comme clé dans un dictionnaire qui a la clé et les valeurs de l'aide2numplays, défini comme ses valeurs. Tout cela dans l'espoir que le fichier produira un résultat incluant (nom de l'artiste, identifiant de l'artiste, fréquence des pièces). Il est à noter que le premier fichier fournit le nom de l'artiste et l'identifiant de l'artiste, tandis que le second fichier fournit l'identifiant de l'utilisateur, l'identifiant de l'artiste et la fréquence par utilisateur. Des idées pour agréger ces fréquences par utilisateur et les afficher dans le format (nom de l'artiste, identifiant de l'artiste, fréquence des lectures)? Voici ce que je suis parvenu à ce jour:Utilisation de setdefault dans Python 3.6 pour afficher (nom, identifiant et nombre de fréquences) à l'aide des informations de deux fichiers différents

import codecs 
aid2name = {} 
d2 = {} 
fp = codecs.open("artists.dat", encoding = "utf-8") 
fp.readline() #skip first line of headers 
for line in fp: 
    line = line.strip() 
    fields = line.split('\t') 
    aid = int(fields[0]) 
    name = fields[1] 
    aid2name = {int(aid), name} 
    d2.setdefault(fields[1], {}) 
    #print (aid2name) 
# do other processing 
    #print(dictionary) 

aid2numplays = {} 
fp = codecs.open("user_artists.dat", encoding = "utf-8") 
fp.readline() #skip first line of headers 
for line in fp: 
    line = line.strip() 
    fields = line.split('\t') 
    uid = int(fields[0]) 
    aid = int(fields[1]) 
    weight = int(fields[2]) 
    aid2numplays = [int(aid), int(weight)] 
    #print(aid2numplays) 
    #print(uid, aid, weight) 

for (d2.fields[1], value) in d2: 
    group = d2.setdefault(d2.fields[1], {}) # key might exist already 
    group.append(aid2numplays) 

print(group) 
+0

Il pourrait aider à voir un exemple de ce que la structure de données finale devrait ressembler, je ne suis pas certain que vous avez l'intention d'utiliser [setdefault] (http://stackoverflow.com/questions/3483520/use-cases-for-the-setdefault-dict-method) – brennan

Répondre

1

Modifier: En ce qui concerne l'utilisation de setdefault, si vous voulez regrouper les données utilisateur par ArtistlD vous pourriez alors:

grouped_data = {} 
for u in users: 
    k, v = u[1], {'userID': u[0], 'weight': u[2]} 
    grouped_data.setdefault(k, []).append(v) 

Ceci est essentiellement le même que l'écriture:

grouped_data = {} 
for u in users: 
    k, v = u[1], {'userID': u[0], 'weight': u[2]} 
    if k in grouped_data: 
     grouped_data[k].append(v) 
    else: 
     grouped_data[k] = [v] 

à titre d'exemple pour la façon de compter le nombre de fois qu'un artiste apparaît dans différentes données des utilisateurs, vous c ould lire les données dans des listes de listes:

with codecs.open("artists.dat", encoding = "utf-8") as f: 
    artists = f.readlines() 

with codecs.open("user_artists.dat", encoding = "utf-8") as f: 
    users = f.readlines() 

artists = [x.strip().split('\t') for x in artists][1:] # [['1', 'MALICE MIZER', .. 
users = [x.strip().split('\t') for x in users][1:] # [['2', '51', '13883'], ..] 

itérer sur les artistes créant un dictionnaire en utilisant la ArtistlD comme une clé. Ajouter un espace réservé pour les statistiques de jeu.

data = {} 
for a in artists: 
    artistID, name = a[0], a[1] 
    data[artistID] = {'name': name, 'plays': 0} 

itérer sur les utilisateurs mettre à jour le dictionnaire chaque ligne:

for u in users: 
    artistID = u[1] 
    data[artistID]['plays'] += 1 

sortie pour données:

{'1': {'name': 'MALICE MIZER', 'plays': 3}, 
'2': {'name': 'Diary of Dreams', 'plays': 12}, 
'3': {'name': 'Carpathian Forest', 'plays': 3}, ..} 

Modifier: itérer sur les données de l'utilisateur et de créer un dictionnaire de tous les artistes associés à un utilisateur nous pourrions:

artist_list = [x.strip().split('\t') for x in artists][1:] 
user_stats_list = [x.strip().split('\t') for x in users][1:] 

artists = {} 
for a in artist_list: 
    artistID, name = a[0], a[1] 
    artists[artistID] = name 

grouped_user_stats = {} 
for u in user_stats_list: 
    userID, artistID, weight = u 
    if userID not in grouped_user_stats: 
     grouped_user_stats[userID] = { artistID: {'name': artists[artistID], 'plays': 1} } 
    else: 
     if artistID not in grouped_user_stats[userID]: 
      grouped_user_stats[userID][artistID] = {'name': artists[artistID], 'plays': 1} 
     else: 
      grouped_user_stats[userID][artistID]['plays'] += 1 
      print('this never happens') 
      # it looks the same artist is never listed twice for the same user 

Sortie:

{'2': {'100': {'name': 'ABC', 'plays': 1}, 
     '51': {'name': 'Duran Duran', 'plays': 1}, 
     '52': {'name': 'Morcheeba', 'plays': 1}, 
     '53': {'name': 'Air', 'plays': 1}, .. }, 
.. 
} 
+0

Pour finalement les afficher dans (format nom de l'artiste, id de l'artiste, fréquence des lectures) format do: '['id': k, ** v} pour k, v dans data.items()] 'ou' [(k, ** v) pour k, v dans data.items()] 'pour une liste de dictionnaires tuples respectifs. – mab

+0

Merci à vous deux. Je l'avais regardé d'un point de vue différent mais j'ai l'impression que c'est en train de cliquer maintenant. Bren, juste par curiosité, comment avez-vous connu les détails sur les sorties sans les fichiers? – pythonuser890

+0

En outre, je me demandais comment agréger le total des pièces par chaque artiste? J'ai lutté pour ajouter les jeux par userID pour les afficher ensuite comme un agrégat. Tous les conseils, les conseils sont vraiment utiles. Merci beaucoup de donner ces conseils avant. – pythonuser890