1

我有一个 3,642,197 行长的 csv 文件,我需要将其从最早日期排序到最晚日期。

我编写了一个搜索数据库的程序,并将包含用户指定的“API”编号的每一行写入一个稍后将用于绘图的文件。最早的日期首先出现在文件中是非常重要的,所以我遇到了这个问题:将这个巨大的文件放在一起的人使用了 excel 中的 3 个不同文件并将其合并到一个 csv 中,所以日期没有排序.

如果我可以格式化数据库以便首先找到所有最早的日期,我认为这将是解决问题的最简单方法。

我对python有点陌生,我正试图围绕如何按日期对这个文件进行排序。我尝试在 excel 和 libreoffice calc 中执行此操作,但它超过了最大行数。

以下是文件中文本的示例:

"01/31/1986","25003050040000","SHA","香农",121,"",0,0,1324,31,False,P,""

我有 2013 年到 1986 年的记录,必须对它们进行排序,但无法理解这是如何完成的。从我搜索的内容中,我找不到任何我能理解的东西。

非常感谢和赞赏提前!

编辑:最简单的方法是使用 Linux/unix。一个简单的排序命令正是我所说的。

前任。排序 -t/ -g -r -k3 -k1 -k2 infile.csv > outfile.csv

-t/ 设置分隔符,-g 按数值排序,-r 从最后一行开始读取文件。-k3 是年份字段,-k1 是月份字段,-k2 是日期字段。它将按年排序,然后按月排序,然后按天排序。如果您需要按时间顺序对巨大的 csv 文件进行排序,并且它不适合 excel,这是迄今为止我找到的最简单的解决方案。

注意:如果您的数据是逗号分隔的,并且日期字段后面的字段是数字,您需要将第一个逗号分隔符更改为 /,这样它就不会在排序中包含尾随数据。

前任。02/25/1987,204928169562,62563959401,16375840 <-- 这需要更改为 02/25/1987/204928169562,62563959401,16375840 以便您的数据正确排序。

4

3 回答 3

1

您可以使用sedandsort来完成该任务:

cat big_file.csv | \
sed -e 's,^"\(..\)/\(..\)/\(....\)",\3\1\2,' | \
sort | \
sed -e 's,^\(....\)\(..\)\(..\),"\2/\3/\1",' > sorted_file.csv

第一个sed命令转换:

"01/31/1986","25003050040000","SHA","Shannon",121,"",0,0,1324,31,False,P,""

19860131,"25003050040000","SHA","Shannon",121,"",0,0,1324,31,False,P,""

然后这些行按词法排序sort

第二个sed恢复美国日期格式。

>排序后的文本放入文件中。


如果您想改用 Python:

lines = ((line[7:11], line[1:3], line[4:6]), line) # tuples of (date, line)
         for line in open('big_file.csv'))         # that's a "generator"
sorted_lines = (line[1] for line in sorted(lines)) # sort tuples and omit date
sorted_content = ''.join(lines)                    # recreated CSV file

这个想法与shell脚本完全相同。


我刚刚注意到,您可以使用@user2864740提到key的 sorted 参数更容易地做到这一点:

content = ''.join(sorted(open('big_file.csv'),
                         key=lambda line: (line[7:11], line[1:3], line[4:6])))
于 2013-10-30T01:24:16.987 回答
1

您可以阅读 csv 文件,将愚蠢的日期转换为ISO 8601格式,以便它们正确排序并继续:

csv_txt='''\
"01/31/1987","25003050040000","SHA","Shannon",121,"",0,0,1324,31,False,P,""
"01/31/1986","25003050040000","SHA","Shannon",121,"",0,0,1324,31,False,P,""
"01/31/1993","25003050040000","SHA","Shannon",121,"",0,0,1324,31,False,P,""
"01/28/1993","25003050040000","SHA","Shannon",121,"",0,0,1324,31,False,P,""
"01/31/2013","25003050040000","SHA","Shannon",121,"",0,0,1324,31,False,P,""'''

import csv
import datetime

data=[]
for line in csv.reader(csv_txt.splitlines()):
    d=datetime.datetime.strptime(line[0],'%m/%d/%Y')
    data.append([d.isoformat().partition('T')[0]]+line[1:])

for e in sorted(data):
    print e

印刷:

['1986-01-31', '25003050040000', 'SHA', 'Shannon', '121', '', '0', '0', '1324', '31', 'False', 'P', '']
['1987-01-31', '25003050040000', 'SHA', 'Shannon', '121', '', '0', '0', '1324', '31', 'False', 'P', '']
['1993-01-28', '25003050040000', 'SHA', 'Shannon', '121', '', '0', '0', '1324', '31', 'False', 'P', '']
['1993-01-31', '25003050040000', 'SHA', 'Shannon', '121', '', '0', '0', '1324', '31', 'False', 'P', '']
['2013-01-31', '25003050040000', 'SHA', 'Shannon', '121', '', '0', '0', '1324', '31', 'False', 'P', '']
于 2013-10-30T01:40:46.910 回答
1

一种方法(也许不是最聪明的,但它会起作用)是将所有行读入list. 然后数据看起来像:

# lines -> ['"01/31/1986",..', '"4/30/2000",..', ..]

然后可以使用映射排序。这为实际排序的每个项目建立了映射。在这种情况下,需要将“mm/dd/yyyy”变成有序的东西。可能的键可能是:“YYYYMMDD”、一个datetime对象,或者可能是一个纪元时间戳。

例如:

def lineKey (v):  # v -> '"01/31/1986",..'
    r = v[1:11]   # r -> '01/31/1986'
    return datetime.strptime(r, "%m/%d/%Y")

lines.sort(key=lineKey)
# or; lines = sorted(lines, key=lineKey)
于 2013-10-30T01:31:41.007 回答