使用从两列计算的密钥对CSV进行排序,先获取n个最大值

时间:2013-05-23 06:39:25

标签: python sorting csv

Python业余爱好者......让我们说这里有一个示例csv文件的片段:

Country, Year, GDP, Population
Country1,2002,44545,24352
Country2,2004,14325,75677
Country3,2005,23132412,1345234
Country4,,2312421,12412

我需要通过降低某一年的人均GDP(GDP /人口),比如2002年来对文件进行排序,然后抓住人均GDP值最大的前10行。

到目前为止,在我将csv导入'data'变量后,我使用以下方法获取所有2002数据而不丢失字段:

data_2 = []
for row in data:
if row[1] == '2002' and row[2]!= ' ' and row[3] != ' ':
    data_2.append(row)

我需要找到一些方法来按data_2降序排序row[2]/row[3],最好不使用类,然后抓住每个最大10个值的每一行,然后写入另一个csv 。如果有人能指出我正确的方向,我会永远感激,因为我尝试了无数的谷歌......

3 个答案:

答案 0 :(得分:3)

这种方法可让您对文件进行一次扫描,以获得每个国家/地区的前10名...

使用pandas模块可以在没有heapq的情况下执行此操作,以下是未经测试的,但应该是您参考相应文档并根据您的目的进行调整的基础:

import csv
import heapq
from itertools import islice

freqs = {}
with open('yourfile') as fin:
    csvin = csv.reader(fin)
    rows_with_gdp = ([float(row[2]) / float(row[3])] + row for row in islice(csvin, 1, None) if row[2] and row[3])
    for row in rows_with_gdp:
        cnt = freqs.setdefault(row[2], [[]] * 10) # 2 = year, 10 = num to keep
        heapq.heappushpop(cnt, row)

for year, vals in freqs.iteritems():
    print year, [row[1:] for row in sorted(filter(None, vals), reverse=True)]

答案 1 :(得分:2)

相关模块将是:

  • csv 用于解析输入
  • collections.namedtuple 命名字段
  • filter()函数用于提取指定的年份范围
  • heapq.nlargest()以查找最大值
  • pprint.pprint() for nice output

这里有一点让你入门(我会做到这一切,但是让别人编写整个程序并剥夺你完成它的乐趣是多么有趣):

from __future__ import division
import csv, collections, heapq, pprint

filecontents = '''\
Country, Year, GDP, Population
Country1,2002,44545,24352
Country2,2004,14325,75677
Country3,2004,23132412,1345234
Country4,2004,2312421,12412
'''

CountryStats = collections.namedtuple('CountryStats', ['country', 'year', 'gdp', 'population'])
dialect = csv.Sniffer().sniff(filecontents)

data = []
for country, year, gdp, pop in csv.reader(filecontents.splitlines()[1:], dialect):
    row = CountryStats(country, int(year), int(gdp), int(pop))
    if row.year == 2004:
        data.append(row)

data.sort(key = lambda s: s.gdp / s.population)
pprint.pprint(data)

答案 2 :(得分:0)

使用sort函数的可选键参数:

array.sort(key=lambda x: x[2])

将使用其第三个元素作为键对array进行排序。 key参数的值应该是一个lambda表达式,它接受一个参数(被排序的数组的任意元素)并返回用于排序的键。

对于你的GDP例子,要使用的lambda函数是:

lambda x: float(x[2])/float(x[3]) # x[2] is GDP, x[3] is population

float函数将CSV字段从字符串转换为浮点数。由于无法保证这将成功(格式不正确,数据不正确等),我通常会在排序之前将数据插入到数组中。你应该明确地使用浮点除法,因为整数除法不会给你预期的结果。如果您发现自己经常这样做,那么更改除法运算符的行为是一个选项(http://www.python.org/dev/peps/pep-0238/和相关链接)。