1
votes

Convertir les petits nombres en une échelle de 0 à 10

J'ai une liste d'urls-> petits nombres. les nombres représentent l'importance de chaque URL

res1 = round(x*9/maxpri)+1
res2 = round(((x-minpri)/(maxpri-minpri))*10, 2)

disons la somme des valeurs = 1 Je voudrais représenter ces nombres sur une échelle de 0 à 10 et maintenir une sorte de différence de rapport entre les nombres

url, value, scaled_value
https://mywebsite.com/p/1, 0.00212, 10
https://mywebsite.com/p/2, 0.00208, 9
https://mywebsite.com/p/3, 0.00201, 9
https://mywebsite.com/p/4, 0.00138, 6
https://mywebsite.com/p/5, 0.00067, 3
https://mywebsite.com/p/1, 0.00001, 1
...

quelque chose comme ça (je ne sais pas si le rapport la différence ici est maintenue tho) n'importe qui peut aider avec les maths? merci

#Update

grâce à l'aide @annZen, j'ai essayé deux approches, mais les résultats sont différents, je ne sais pas pourquoi. si quelqu'un peut vous aider?

 enter image description here

voici les deux formules que j'ai utilisées:

url, value
https://mywebsite.com/p/1, 0.00212
https://mywebsite.com/p/2, 0.00208
https://mywebsite.com/p/3, 0.00201
https://mywebsite.com/p/4, 0.00138
https://mywebsite.com/p/5, 0.00067
https://mywebsite.com/p/1, 0.00001
...


2 commentaires

Vous avez dit une échelle de 0 à 10, mais vos deux formules res1 donnent des valeurs de 1 à 10.


merci @alaniwi pensez-vous que cela seul peut expliquer l'énorme différence dans les chiffres? Je veux dire que l'ordre est toujours le même mais les valeurs sont différentes


3 Réponses :


0
votes

Si vous souhaitez conserver une différence de rapport définie entre les nombres, vous pouvez définir le plus petit nombre sur 1 puis régler tous les autres nombres sur num / plus petit .

/ p>

Le problème avec cette approche est qu'elle ne garantit pas que chaque URL est définie sur un nombre compris entre 0 - 10 . Dans l'exemple ci-dessus, il définirait les nombres sur 212, 208, 201, 138, 67 et 1 respectivement.

Si vous avez vraiment besoin de définir chaque nombre entre une certaine plage spécifiée, vous devez d'abord définir la plus petite URL pour qu'elle ait une importance 0 et la plus grande URL à avoir importance 10 . Ensuite, tous les autres points se trouveraient sur une ligne avec la pente (valeur max - valeur min) / 10 . L'image ci-dessous présente ce concept:

 entrez la description de l'image ici

Dans cette image, les valeurs y des points représentent leur valeur URL et les coordonnées x représentent l'importance des points.


2 commentaires

hé @Telescope merci pour votre réponse, j'ai essayé cette approche, qu'en pensez-vous? statistiques. stackexchange.com/questions/70801/…


Cette approche suit une logique similaire à mon approche. Je pense que cela fonctionnera très bien pour vos besoins.



1
votes

Voici un moyen:

num = [round(((x-min(lst2))/(max(lst2)-min(lst2)))*10, 2) for x in lst2]

Avant:

[10.0, 9.81, 9.48, 6.51, 3.16, 0.05]
[10.0, 9.81, 9.48, 6.49, 3.13, 0.0]

Après:

num1 = [round(x*10/max(lst2), 2) for x in lst2]
num2 = [round(((x-min(lst2))/(max(lst2)-min(lst2)))*10, 2) for x in lst2]
print(num1)
print(num2)



UPDATE:

La partie de mon code qui effectue la conversion est:

round(x*9/max(lst2), 2)+1
round(x*10/max(lst2), 2)

lst2 est simplement la liste des flottants extraits du fichier. Vous avez mis à jour la question pour moi pour expliquer la différence entre

[10.0, 9.83, 9.53, 6.86, 3.84, 1.04]
[10.0, 9.81, 9.48, 6.49, 3.13, 0.0]

Voyons d'abord ensuite dans ma liste de compréhension:

num1 = [round(x*9/max(lst2), 2)+1 for x in lst2]
num2 = [round(((x-min(lst2))/(max(lst2)-min(lst2)))*10, 2) for x in lst2]
print(num1)
print(num2)

Résultat:

[10, 10, 10, 7, 4, 1]
[10.0, 9.81, 9.48, 6.49, 3.13, 0.0]

La première différence la plus claire est que j'ai arrondi ma réponse à l'entier le plus proche. Sans cela, ce serait:

num1 = [round(x*9/max(lst2))+1 for x in lst2]
num2 = [round(((x-min(lst2))/(max(lst2)-min(lst2)))*10, 2) for x in lst2]
print(num1)
print(num2)

Sortie:

res1 = round(x*9/maxpri)+1
res2 = round(((x-minpri)/(maxpri-minpri))*10, 2)

Les valeurs sont maintenant très proches, mais il y en a une de plus chose. Mon code suppose que la valeur minimale des valeurs mises à l'échelle est 1 , car j'ai vu dans votre message https://mywebsite.com/p/1, 0.00001, 1 . Je réalise maintenant que vous avez indiqué 0-10, pas 1-10. Alors qu'une autre consiste à changer le 9 (10-1 = 9) en 10 (10-0 = 10), et en supprimant le +1 code>:

num = [round(a*9/max(lst2))+1 for a in lst2]

url, value, scaled_value
https://mywebsite.com/p/1, 0.00212, 10
https://mywebsite.com/p/2, 0.00208, 10
https://mywebsite.com/p/3, 0.00201, 10
https://mywebsite.com/p/4, 0.00138, 7
https://mywebsite.com/p/5, 0.00067, 4
https://mywebsite.com/p/1, 0.00001, 1

Sortie:

url, value
https://mywebsite.com/p/1, 0.00212
https://mywebsite.com/p/2, 0.00208
https://mywebsite.com/p/3, 0.00201
https://mywebsite.com/p/4, 0.00138
https://mywebsite.com/p/5, 0.00067
https://mywebsite.com/p/1, 0.00001

Encore un peu différent , c'est parce que j'ai supposé que la valeur minimale dans votre colonne est 0 , parce que vous n'avez pas montré tout votre tableau. Mais dans ce cas, c'est 0,00001 . Alors, allez avec:

with open('file.txt', 'r') as p:
    lst = p.read().splitlines() # List all the lines of the file

lst2 = [float(i.split(', ')[1]) for i in lst[1:]] # List all the floats

num = [round(a*9/max(lst2))+1 for a in lst2] # List all the scaled numbers

for i,(l,n) in enumerate(zip(lst,['scaled_value']+num)):
    lst[i] = f"{l}, {n}" # Add the 'scaled_value' column

with open('file.txt', 'w') as p:
    p.write('\n'.join(lst)) # Write the updated data into the file

Résumé: Mon code supposait que vous vouliez que les nombres soient mis à l'échelle de 1 à 10, au lieu de 0 à 10, et mon code supposait que la valeur minimale pour vos données est égal à 0, ce qui pourrait ne pas être le cas.


9 commentaires

hé @annZen merci pour votre réponse, j'ai essayé cette approche, qu'en pensez-vous? statistiques. stackexchange.com/questions/70801/…


@DanyM En fait, la méthode que j'ai utilisée était la même logique :)


oui @annZen mais je n'obtiens pas les mêmes résultats, j'ai mis à jour le fil avec mes résultats, merci de me dire ce que vous pensez


Bien sûr, donnez-moi une minute.


@DanyM mis à jour.


très clair @annZen, merci beaucoup. où pouvons-nous vous suivre?


Je suis désolé, je n'ai pas eu la dernière partie?


oh désolé, la question était de savoir où nous pouvons vous trouver pour discuter plus loin, cela ne vous dérange pas, j'ai vu que vous avez un groupe facebook et une chaîne youtube :)


continuons cette discussion dans le chat .



0
votes

Si c'est pour le code de production, alors je suggère csv.DictReader et csv.DictWriter pour un code facile à lire lorsque vous y reviendrez plus tard . Par exemple:

from csv import DictReader, DictWriter

scaled_field_name = 'scaled_value'

with open('input.csv') as fin:
    csvin = DictReader(fin, skipinitialspace=True)
    rows = list(csvin)

values = [float(row['value']) for row in rows]
min_value = min(values)
max_value = max(values)
for row, value in zip(rows, values):
    scaled = 10 * (value - min_value) / (max_value - min_value)
    row[scaled_field_name] = str(round(scaled))

with open('output.csv', 'w') as fout:
    csvout = DictWriter(fout, csvin.fieldnames + [scaled_field_name])
    csvout.writerows(rows)

(Remarque: il n'écrira pas d'espaces après les virgules, mais cela devrait être normal pour CSV.)


0 commentaires