【问题标题】:Find max number in .CSV file in Python在 Python 中查找 .CSV 文件中的最大数量
【发布时间】:2014-12-20 12:47:29
【问题描述】:

我有一个 .csv 文件,在 Excel 中打开时看起来像这样:

我的代码:

myfile = open("/Users/it/Desktop/Python/In-Class Programs/countries.csv", "rb")

    countries = []
    for item in myfile:
        a = item.split(",")
        countries.append(a)

    hdi_list = []
    for acountry in countries:
        hdi = acountry[3]

        try:
            hdi_list.append(float(hdi))
        except:
            pass

    average = round(sum(hdi_list)/len(hdi_list), 2)
    maxNumber = round(max(hdi_list), 2)
    minNumber = round(min(hdi_list), 2)

此代码运行良好,但是,当我找到最大值、最小值或平均值时,我需要获取相应的国家名称并将其打印出来。

如何更改我的代码以同时获取最小值、最大值、平均值的国家/地区名称?

【问题讨论】:

  • 也许使用字典而不是列表?将国家作为键,将值作为值吗?然后找到最高值的键?
  • 这是一个文本文件,为什么不用文本模式打开...'rt')
  • 您确定此代码有效吗?国家名称中有逗号,在这种情况下应该有一个额外的字段,值是一个字段。
  • “平均国家/地区名称”是什么样的?
  • @ArtOfWarfare 以 HDI 作为键的字典将防止重复的 HDI 被平均计算

标签: python loops csv max


【解决方案1】:

不要将值直接放在列表中,而是使用元组,如下所示:

hdi_list.append((float(hdi), acountry[1]))

那么你可以用这个来代替:

maxTuple = max(hdi_list)
maxNumber = round(maxTuple[0], 2)
maxCountry = maxTuple[1]

【讨论】:

  • 如果两个国家的最大 HDI 相同怎么办?
  • @RafaelBarros 如果您有关于两个具有最大 HDI 的国家/地区的规范,请将其添加到您的问题中。你试过看看会发生什么吗? max([(1, 'a'),(1 , 'b'), (0, 'c')])
  • @wwii 不是我的问题,只是提前考虑
  • @RafaelBarros - 对元组列表进行排序将首先按第一个字段排序,然后按第二个字段排序。因此,如果多个国家/地区具有相同的最大 HDI,则将返回按字母顺序排列的最后一个*。这个问题没有具体说明如果多个国家的 HDI 最大值并列应该发生什么,所以我选择了这个,因为它看起来是做提问者说他​​们想要发生的事情的最简单方法。 *因为我们使用的是max(),而不是min(),所以当按字母顺序排序时,我们得到的是最后一个,而不是第一个。
  • 我认为您忘记了 append 参数周围的括号。
【解决方案2】:

使用下面的pandas 模块,[4][5][6] 应该分别显示最大值、最小值和平均值。请注意,以下数据与您保存的国家/地区数据不匹配。

In [1]: import pandas as pd

In [2]: df = pd.read_csv("hdi.csv")

In [3]: df
Out[3]: 
         Country    HDI
0         Norway  83.27
1      Australia  80.77
2    Netherlands  87.00
3  United States  87.43
4    New Zealand  87.43
5         Canada  87.66
6        Ireland  75.47
7  Liechtenstein  88.97
8        Germany  86.31
9         Sweden  80.54

In [4]: df.ix[df["HDI"].idxmax()]
Out[4]: 
Country    Liechtenstein
HDI                88.97
Name: 7, dtype: object

In [5]: df.ix[df["HDI"].idxmin()]
Out[5]: 
Country    Ireland
HDI          75.47
Name: 6, dtype: object

In [6]: df["HDI"].mean()
Out[6]: 84.484999999999985

假设LiechtensteinGermany 都有最大值:

In [15]: df
Out[15]: 
         Country    HDI
0         Norway  83.27
1      Australia  80.77
2    Netherlands  87.00
3  United States  87.43
4    New Zealand  87.43
5         Canada  87.66
6        Ireland  75.47
7  Liechtenstein  88.97
8        Germany  88.97
9         Sweden  80.54

In [16]: df[df["HDI"] == df["HDI"].max()]
Out[16]: 
         Country    HDI
7  Liechtenstein  88.97
8        Germany  88.97

同样的逻辑可以应用于最小值。

【讨论】:

  • 在您使用pandasiPy 的事实之间,我什至无法理解这一点。 IE,你的最后一行输入,df[df["HDI"] == df["HDI"].max()]... 这甚至是有效的 Python 吗?下标中间的相等检查对我来说看起来很奇怪......除非这是我以前从未见过的某种高级切片符号?还是只有iPy 和/或pandas才有可能?
  • 这是一个有效的pandas 表示法。基本上读作get dataframe view of df where column HDI of df is equal to the maximum value in column HDI of df。我能说什么,pandas 早餐吃 CSV 处理。
【解决方案3】:

以下方法与您的实现非常接近,我认为它可能有用。但是,如果您开始使用更大或更复杂的 csv 文件,您应该查看像“csv.reader”或“Pandas”这样的包(如前所述)。它们在处理复杂的 .csv 数据时更加健壮和高效。您还可以使用“xlrd”包在 Excel 中工作。

在我看来,引用国家名称及其各自值的最简单解决方案是结合您的“for 循环”。与其循环遍历数据两次(在两个单独的“for 循环”中)并创建两个单独的列表,不如使用单个“for 循环”并创建一个包含相关数据的字典(即“国家名称”、“hdi”)。您也可以创建一个元组(如前所述),但我认为字典更明确。

myfile = open("/Users/it/Desktop/Python/In-Class Programs/countries.csv", "rb")

countries = []
for line in myfile:
    country_name = line.split(",")[1]
    value_of_interest = float(line.split(",")[3])
    countries.append(
        {"Country Name": country_name, 
         "Value of Interest": value_of_interest})

ave_value = sum([country["Value of Interest"] for country in countries])/len(countries)
max_value = max([country["Value of Interest"] for country in countries])
min_value = min([country["Value of Interest"] for country in countries])

print "Country Average == ", ave_value
for country in countries:
    if country["Value of Interest"] == max_value:
        print "Max == {country}:{value}".format(country["Country Name"], country["Value of Interest"])
    if country["Value of Interest"] == min_value:
        print "Min == {country}:{value}".format(country["Country Name"], country["Value of Interest"])

请注意,如果多个国家/地区具有相同的最小值/最大值,则此方法会返回它们。

如果您对创建单独的列表(如您当前的实现)一无所知,您可能会考虑使用 zip() 来连接您的列表(按索引),其中

zip(countries, hdi_list) = [(countries[1], hdi_list[1]), ...]

例如:

for country in zip(countries, hdi_list):
    if country[1] == max_value:
        print country[0], country[1]

将类似的逻辑应用于最小值和平均值。此方法有效,但不太明确且更难维护。

【讨论】:

    猜你喜欢
    • 2019-06-10
    • 1970-01-01
    • 2014-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-11
    相关资源
    最近更新 更多