为了账号安全,请及时绑定邮箱和手机立即绑定

将小数字转换为 0 到 10 的小数位数

将小数字转换为 0 到 10 的小数位数

牛魔王的故事 2023-02-15 16:03:23
我有一个 urls->small numbers 列表。数字代表每个网址的重要性url, valuehttps://mywebsite.com/p/1, 0.00212https://mywebsite.com/p/2, 0.00208https://mywebsite.com/p/3, 0.00201https://mywebsite.com/p/4, 0.00138https://mywebsite.com/p/5, 0.00067https://mywebsite.com/p/1, 0.00001...假设值的总和 = 1 我想在 0-10 的范围内表示这些数字并保持数字之间的一种比率差异url, value, scaled_valuehttps://mywebsite.com/p/1, 0.00212, 10https://mywebsite.com/p/2, 0.00208, 9https://mywebsite.com/p/3, 0.00201, 9https://mywebsite.com/p/4, 0.00138, 6https://mywebsite.com/p/5, 0.00067, 3https://mywebsite.com/p/1, 0.00001, 1...像这样的东西(我不知道这里的比率差异是否保持不变)有人可以帮助数学吗?谢谢#更新感谢@annZen 的帮助,我尝试了两种方法,但结果不同我不知道为什么。如果有人可以帮忙?这是我使用的两个公式:res1 = round(x*9/maxpri)+1res2 = round(((x-minpri)/(maxpri-minpri))*10, 2)
查看完整描述

3 回答

?
慕森卡

TA贡献1806条经验 获得超8个赞

这是一种方法:


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

前:


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

后:


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

更新:


我的代码中进行转换的部分是:


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

wherelst2只是从文件中提取的浮点数列表。您为我更新了问题以解释两者之间的区别


res1 = round(x*9/maxpri)+1

res2 = round(((x-minpri)/(maxpri-minpri))*10, 2)

让我们先看看我的列表理解:


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)

输出:


[10, 10, 10, 7, 4, 1]

[10.0, 9.81, 9.48, 6.49, 3.13, 0.0]

第一个最明显的区别是我将答案四舍五入为最接近的整数。没有它,它将是:


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)

输出:


[10.0, 9.83, 9.53, 6.86, 3.84, 1.04]

[10.0, 9.81, 9.48, 6.49, 3.13, 0.0]

这些值现在非常接近,但还有一件事。我的代码假定缩放值的最小值为1,因为我在您的帖子中看到了https://mywebsite.com/p/1, 0.00001, 1。我现在意识到你说的是 0-10,而不是 1-10。因此,另一个是将 (10-1=9) 更改9为10(10-0=10),并删除+1:


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

round(x*10/max(lst2), 2)

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)

输出:


[10.0, 9.81, 9.48, 6.51, 3.16, 0.05]

[10.0, 9.81, 9.48, 6.49, 3.13, 0.0]

仍然有点不同,那是因为我假设你列中的最小值是0,因为你没有显示整个数组。但在这种情况下,它是0.00001. 所以,继续:


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

摘要:我的代码假定您希望数字从 1 缩放到 10,而不是 0 到 10,并且我的代码假定您的数据的最小值为 0,但事实可能并非如此。


查看完整回答
反对 回复 2023-02-15
?
慕森王

TA贡献1777条经验 获得超3个赞

如果这是用于生产代码,那么我建议csv.DictReader您csv.DictWriter稍后回过头来使用易于阅读的代码。例如:


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)

(注意:逗号后面不会写空格,不过对于CSV应该是正常的。)


查看完整回答
反对 回复 2023-02-15
?
斯蒂芬大帝

TA贡献1827条经验 获得超8个赞

如果要在数字之间保持一定的比率差异,可以将最小的数字设置为1然后将每个其他数字设置为num/smallest

这种方法的问题在于它不能保证每个 URL 都设置为来自0 - 10. 在上面的示例中,它将分别设置数字212, 208, 201, 138, 67, and 1

如果您确实需要将每个数字都设置在某个指定范围之间,则首先将最小的 URL 设置为 importance 0,然后将最大的 URL 设置为 importance 10。然后,所有其他点将位于斜率为 的直线上(max value - min value)/10。下图展示了这个概念:

//img1.sycdn.imooc.com//63ec920e0001618206540452.jpg

在这张图片中,点的 y 值表示它们的 URL 值,x 坐标表示点的重要性。



查看完整回答
反对 回复 2023-02-15
  • 3 回答
  • 0 关注
  • 129 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信