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,但事實可能并非如此。

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應該是正常的。)

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
。下圖展示了這個概念:
在這張圖片中,點的 y 值表示它們的 URL 值,x 坐標表示點的重要性。
添加回答
舉報