当值是大浮点数时按值对字典进行排序(尝试了 lambda 和 itemgetter 但没有得到正确的结果)

Sorting a dictionary by value when the values are large float numbers (tried lambda and itemgetter but didn't get proper result)

我有一个包含人名和平均值的 csv 文件,如下所示:

mandana,7.5
hamid,6.066666666666666
sina,11.285714285714286
sara,9.75
soheila,7.833333333333333
ali,5.0
sarvin,11.375

我想按平均值排序并将其写入另一个文件。我试过 lambda 和 itemgetter 但没有得到正确的结果。这是我的代码:

def calculate_sorted_averages(file1, file2):
with open (r'C:\Users\sony\Desktop\Python with Jadi\file1.csv', 'r') as f1:
    reader=csv.reader(f1)
    d={}
    for row in reader:
        name=row[0]
        average=row[1]
        d[name]=average
    sorted_dict=OrderedDict(sorted(d.items(), key=operator.itemgetter(1), reverse=True))
    with open (r'C:\Users\sony\Desktop\Python with Jadi\file2.csv', 'w', newline='') as f2:
        for key in sorted_dict.keys():
            writer=csv.writer(f2)
            writer.writerow([key,sorted_dict[key]])

这是我的输出:

sara,9.75
soheila,7.833333333333333
mandana,7.5
hamid,6.066666666666666
ali,5.0
sarvin,11.375
sina,11.285714285714286

如您所见,它没有排序。我也尝试过 lambda 但它没有用。我现在很沮丧,不知道该怎么办。谁能帮我?谢谢

您可以为此尝试 pandas 模块。

pandas.read_csv() 函数将读取 csv 文件,您将其路径作为函数内部的参数传入,并将其转换为 pandas 数据帧,或者更简单地说,它将显示 table 里面 Python.

import pandas as pd

df = pd.read_csv("C:\Users\sony\Desktop\Python with Jadi\file1.csv")
df.columns = ["Name", "Value"]    # To set the column names. Only do this if the dataframe doesn't already have a column name.
sorted_df = df.sort_values(by = "Value")    # Sorting the dataframe by the values in the "Value" column

输出-

Name Value
5 ali 5.0
1 hamid 6.066666666666666
0 mandana 7.5
4 soheila 7.833333333333333
3 sara 9.75
2 sina 11.285714285714286
6 sarvin 11.375

您可以使用 to_csv() 将此数据框转换回 csv 文件。传入文件路径作为参数,如果不希望将索引添加为列,则设置index = False

Pandas 可用于此 - 您可以使用 pip install pandas

安装它
import pandas as pd

df = pd.read_csv('filename.csv')
df.columns = ['name', 'value']
df.sort_values('value', inplace=True, ascending=True)

print(df)

你得到结果是因为你按字典顺序排序(将你的浮点数作为字符串进行比较)而不是按它们的数值排序。

您所缺少的只是将数值转换为 float 就大功告成了,并像往常一样使用 key=operator.itemgetter(1)

进行排序
def calculate_sorted_averages(file1, file2):
    d = {}
    with open (r'path/to/unsorted.csv', 'r') as f1:
        reader=csv.reader(f1)
        for row in reader:
            name=row[0]
            average=row[1]
            d[name]=float(average)
    sorted_dict=OrderedDict(sorted(d.items(), key=operator.itemgetter(1), reverse=True))
    with open (r'path/to/sorted.csv', 'w', newline='') as f2:
        for key in sorted_dict.keys():
            writer=csv.writer(f2)
            writer.writerow([key,sorted_dict[key]])
aaa = {'0': ['mandana', 7.5], '1': ['hamid', 6.066666666666666], '2': ['sina', 11.285714285714286], '3': ['sara', 9.75],
       '4': ['soheila', 7.833333333333333], '5': ['ali', 5.0], '6': ['sarvin', 11.375]}

sorted_ = sorted(aaa.items(), key=lambda x: x[1][1])
sorted_ = dict(sorted_)

输出

{'5': ['ali', 5.0], '1': ['hamid', 6.066666666666666], '0': ['mandana', 7.5], '4': ['soheila', 7.833333333333333], '3': ['sara', 9.75], '2': ['sina', 11.285714285714286], '6': ['sarvin', 11.375]}

你没有显示整本字典的键。所以我创建了我的 'aaa'。按第二个元素排序。

默认情况下,从文件中读取的文本,有或没有 csv.reader,都存储在字符串中。您需要在每一行的第二个元素上调用 float,将其解释为 floating-point 数字。

我认为在这里使用 OrderedDict 有点矫枉过正。调用 sorted 一次就够了。

import csv

def calculate_sorted_averages(filename_input, filename_output):
    with open(filename_input, 'r') as f1:
        reader=csv.reader(f1)
        sorted_rows = sorted(reader, key=lambda x: float(x[1]))
    with open(filename_output, 'w') as f2:
        writer = csv.writer(f2)
        writer.writerows(sorted_rows)

calculate_sorted_averages('file1.csv', 'file2.csv')

结果:

$ cat file1.csv 
mandana,7.5
hamid,6.066666666666666
sina,11.285714285714286
sara,9.75
soheila,7.833333333333333
ali,5.0
sarvin,11.375

$ cat file2.csv
ali,5.0
hamid,6.066666666666666
mandana,7.5
soheila,7.833333333333333
sara,9.75
sina,11.285714285714286
sarvin,11.375