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?
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 ...
3 Réponses :
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:
Dans cette image, les valeurs y des points représentent leur valeur URL et les coordonnées x représentent l'importance des points.
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.
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)
où 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
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 .
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.)
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