在Python中排序CSV

7 投票
4 回答
20959 浏览
提问于 2025-04-15 18:10

我原以为用Python对一个CSV文件进行多字段的排序(无论是文本还是数字)是个已经解决的问题。但我找不到任何示例代码,除了专门针对日期字段排序的代码。

那么,如何对一个相对较大的CSV文件(有几万行)按多个字段进行排序呢?

如果能提供一些Python代码示例就太好了。

4 个回答

2

这是缺少的 convert() 函数,来自于罗伯特对亚历克斯回答的修正:

>>> def convert(convert_funcs, seq):
...    return [
...        item if func is None else func(item)
...        for func, item in zip(convert_funcs, seq)
...        ]
...
>>> convert(
...     (None, float, lambda x: x.strip().lower()),
...     [" text ", "123.45", " TEXT "]
...     )
[' text ', 123.45, 'text']
>>>

我把第一个参数的名字改了,目的是为了强调这个按列处理的函数不仅仅是类型转换,它可以满足你的需求。这里用 None 来表示不进行任何转换。

10

Python的排序功能只在内存中工作;不过,在现代计算机上,成千上万行的数据通常都能轻松放进内存里。所以:

import csv

def sortcsvbymanyfields(csvfilename, themanyfieldscolumnnumbers):
  with open(csvfilename, 'rb') as f:
    readit = csv.reader(f)
    thedata = list(readit)
  thedata.sort(key=operator.itemgetter(*themanyfieldscolumnnumbers))
  with open(csvfilename, 'wb') as f:
    writeit = csv.writer(f)
    writeit.writerows(thedata)
4

这是Alex的回答,经过修改以支持列数据类型:

import csv
import operator

def sort_csv(csv_filename, types, sort_key_columns):
    """sort (and rewrite) a csv file.
    types:  data types (conversion functions) for each column in the file
    sort_key_columns: column numbers of columns to sort by"""
    data = []
    with open(csv_filename, 'rb') as f:
        for row in csv.reader(f):
            data.append(convert(types, row))
    data.sort(key=operator.itemgetter(*sort_key_columns))
    with open(csv_filename, 'wb') as f:
        csv.writer(f).writerows(data)

编辑:

我犯了个傻。我几天前在IDLE里玩各种东西,写了一个convert函数。结果我忘了自己写过这个函数,而且IDLE也很久没关了——所以当我写上面的内容时,我以为convert是一个内置函数。可惜并不是。

不过这是我的实现,虽然John Machin的实现更好:

def convert(types, values):
    return [t(v) for t, v in zip(types, values)]

用法:

import datetime
def date(s):
    return datetime.strptime(s, '%m/%d/%y')

>>> convert((int, date, str), ('1', '2/15/09', 'z'))
[1, datetime.datetime(2009, 2, 15, 0, 0), 'z']

撰写回答