在Python中按日期排序CSV

4 投票
3 回答
6723 浏览
提问于 2025-04-15 16:13

我想对一个CSV文件进行排序,想要按照日期从新到旧排序,也就是最新的在最前面。

def SortCsvByField( filename, fieldNo, sep = ',' ):
   records = [line.split(sep) for line in file(filename)]

这部分其实挺简单的,但我该怎么比较日期呢?

3 个回答

2

假设你已经知道日期的格式,并且这些日期在你的CSV文件的第一列:

>>> import csv
>>> from datetime import datetime
>>> def date_key(row):
        return datetime.strptime(row[1].strip(), "%m/%d/%Y")

>>> with open('c:\\temp\\test\\date_test.csv', 'rb') as f:
        data = list(csv.reader(f))

>>> data
[['foo', ' 3/11/2004'], ['bar', ' 2/15/2001'], ['baz', '11/15/2007'], ['bat', '10/13/2002']]
>>> data.sort(key=date_key)
>>> data
[['bar', ' 2/15/2001'], ['bat', '10/13/2002'], ['foo', ' 3/11/2004'], ['baz', '11/15/2007']]
2

如果你的日期是ISO-8601格式(就是YYYY-MM-DD这种样子),那么你可以直接把它们当作字符串来排序。如果不是这种格式,你就得先把它们转换成日期格式(可以用datetime.strptime这个方法)。

然后你可以用比如说 sorted(records, key=lambda a:a[1]) 这样的方式来排序,前提是日期是在第二个字段里。

5

我建议你安装一个非常好用的 dateutil 模块。(在Ubuntu/Debian系统中,它是通过python-dateutil这个包提供的。)

dateutil可以把日期字符串转换成日期时间对象:它能处理很多不同的日期格式,你根本不需要动手(*):

import dateutil.parser as dparser
date=dparser.parse("Mon May 7 1883 10:36:28")
print(date)
# 1883-05-07 10:36:28

date=dparser.parse("1685-3-21")
print(date)
# 1685-03-21 00:00:00

date=dparser.parse("12/17/1770")
print(date)
# 1770-12-17 00:00:00

注意,parse函数会把“12/17/1770”理解为“MM/DD/YYYY”这种格式。你可以通过parse的 dayfirstyearfirst 选项来改变这个行为。(详细信息可以查看 http://labix.org/python-dateutil

print(type(date))
# <type 'datetime.datetime'>

日期时间对象可以很容易地进行排序:

dates=[dparser.parse("Mon May 7 1883 10:36:28"),dparser.parse("1685-3-21"),dparser.parse("12/17/1770"),]
dates.sort()
print(dates)
# [datetime.date(1685, 3, 21), datetime.date(1770, 12, 17), datetime.date(1833, 5, 7)]

如果你不想安装dateutil包,那你就得自己想办法把日期字符串转换成日期时间对象。这会需要更多的工作,因为你需要自己定义格式。下面的'%Y-%m-%d'就是定义了YYYY-MM-DD这种格式。想了解更多可用的格式代码,可以查看 https://www.php.net/strftime(或者查看strftime的手册页)。

举个例子,

dates=[datetime.datetime.strptime(date_str,'%Y-%m-%d') for date_str in
       ('1883-5-7','1685-3-21','1770-12-17',)]
print([str(date) for date in dates])
# ['1883-05-07 00:00:00', '1685-03-21 00:00:00', '1770-12-17 00:00:00']
dates.sort()
print([str(date) for date in dates])
# ['1685-03-21 00:00:00', '1770-12-17 00:00:00', '1883-05-07 00:00:00']

如果你想在把日期时间对象转换回可打印的字符串时控制格式,可以使用datetime.datetime.strftime()这个方法。

撰写回答