4
votes

Python obtient la moyenne pondérée des clés dict en fonction des valeurs dict

J'essaye d'écrire du code pour trouver la moyenne des clés dans mon dict, mais basé sur les valeurs de dict. Ainsi, par exemple, pour:

d = {1:1_000_000_000_000_000, 2:2_000, 3:1_000_000_000_000_000}

les clés dict seraient:

def get_median_of_dict_keys(d: dict) -> float:
    nums_list = []
    for k,v in d.items():
        if type(v) != int:
            raise TypeError
        nums_list.extend([k] * v)
    
    median = sum(nums_list) / len(nums_list)
    return median

J'ai écrit le code suivant, qui fonctionne pour les petits ensembles de données tels que ci-dessus:

[1,1,2,3,3]

Cela me donne les valeurs que je veux lorsque l'ensemble de données est petit, mais si l'ensemble de données est quelque chose comme:

d = {1:2, 2:1, 3:2}

J'obtiens une erreur de mémoire insuffisante qui, maintenant que j'y pense, a du sens.

Alors, comment puis-je structurer la fonction ci-dessus de manière à gérer également ces ensembles de données plus volumineux? Merci pour votre temps.


12 commentaires

Je pense que ton code calcule la moyenne


les clés de d = {1:2, 2:1, 3:2} sont 1,2,3 non 1,1,2,3,3


Pouvez-vous expliquer comment {1:2, 2:1, 3:2} devrait être [1,1,2,3,3] ?


Dani, désolé, c'est ce que je voulais dire.


Ironkey, je sais, mais je dois compter chaque clé individuellement, ou comme sa propre entrée.


ok donc vous voulez n clés où la valeur de cette clé est n ?


Ann, je dois donc compter chaque clé individuellement. Donc, la clé "1" a une valeur de deux, donc je dois la compter deux fois. Si la clé était 5 et la valeur 14, je devrais la traiter comme s'il y avait quatorze 5. Presque comme un décompte de vote qui aurait pu être fait à l'école primaire, c'est-à-dire que 14 personnes ont voté pour 5.


Ironkey, exactement. Encore une fois, le code fonctionne avec de petits nombres, mais une fois qu'ils deviennent gros, je manque de mémoire.


Modifiez votre question pour trouver la moyenne, ou vous voulez réellement la médiane?


^ que voulez-vous, moyenne ou médiane?


Merci, les amis, j'ai édité le titre. J'apprécie vraiment votre aide!


median balise supprimée, car vous souhaitez rechercher la mean spécifiquement weighted-mean donc les deux ont été ajoutés


3 Réponses :


1
votes

Vous n'avez pas besoin de créer une liste, gardez simplement deux variables en cours d'exécution, l'une contenant la somme totale et l'autre contenant le nombre d'éléments:

2.0

Production

def get_mean_of_dict_keys(d: dict) -> float:
    total = 0
    count = 0
    for k, v in d.items():
        total += k * v
        count += v

    mean = total / count
    return mean


print(get_mean_of_dict_keys({1: 2, 2: 1, 3: 2}))


1 commentaires

Dani, merci beaucoup! J'ai en fait commencé à y penser un peu après avoir posé la question. J'apprécie ton aide!



1
votes

Si tu veux la moyenne

ceci est parfaitement réalisable avec des nombres plus grands:

[i*d[i] for i in d]

# is equivalent to:

lst = []
for i in d:
    lst.append(i*d[i])

production

2666667333.3333335

panne

import numpy as np
d = {1:2000000000, 2:1000, 3:2000000000}
print(np.mean([i*d[i] for i in d]))


1 commentaires

heureux de vous aider :)



0
votes

Ce que vous voulez trouver est weighted average .

Formule:

entrez la description de l'image ici

Où,

  • X 1..n sont des clés dans votre dictionnaire.
  • W 1..n sont des valeurs dans votre dictionnaire.
  • XÌ… est une moyenne pondérée.

Approche pure Python.

Utilisation de itertools.starmap avec operator.mul

np.average([*d.keys()], weights=[*d.values()])
# 2.0

Si vous souhaitez utiliser NumPy

Vous pouvez utiliser np.average ici.

from itertools import starmap
from operator import mul
d = {1:2, 2:1, 3:2}
sum(starmap(mul, d.items()))/sum(d.values())
# 2.0


0 commentaires