对csv文件进行排序超过171列,但有些行的数量较少?

时间:2017-10-09 19:18:54

标签: python csv sorting

我有一个1 GB的CSV文件,大约有100万条记录,每行有171列,我做了一些研究并想出了这段代码。为了测试目的,我已将文件大小减小到5 MB,但仍有171列。只要排序列索引低于50,代码就可以正常工作。即使在49上它也能正常工作,但我的索引为151,153的列。我想用这些列对文件进行排序。

错误:

当我给它索引50或更高时,它会抛出错误:

  data.sort(key=operator.itemgetter(*sort_key_columns))
IndexError: list index out of range

我的代码:

def sort_csv(csv_filename, sort_key_columns):
    data = []
    with open(csv_filename, 'r') as f:
        for row in csv.reader(f):
            data.append(row)
    data.sort(key=operator.itemgetter(*sort_key_columns))
    with open(csv_filename, 'w', newline='') as f:
        csv.writer(f).writerows(data)

sort_csv('Huge_Complete_B2B_file_1_1.csv', [49])

2 个答案:

答案 0 :(得分:1)

您的某个文件似乎包含51列以下的截断行。

如果您不关心输入是否损坏,可以在阅读输入和输入时将其过滤掉。用一行排序:

def sort_csv(csv_filename, sort_key_columns):
    with open(csv_filename, 'r') as f:
        data = sorted([row for row in csv.reader(f) if len(row)>=171],key=operator.itemgetter(*sort_key_columns))
    # then write the file

答案 1 :(得分:1)

您可以编写自己的operator.itemgetter版本来处理短行,您可以根据online documentation中显示的等效代码来处理该行。

下面的自定义版本只为任何缺失的版本提供指定值。这将导致对行进行排序,就好像它在该索引位置具有该值一样。

注意:这假定所有丢失的项目应使用相同的默认MISSING值。如果情况并非如此,则可以增强它以允许为传递给它的序列中的每个索引指定不同的索引。这可能需要额外的论证。

import csv
import operator

def my_itemgetter(*indexes, MISSING=''):
    if len(indexes) == 1:
        index = indexes[0]
        def getter(obj):
            try:
                return obj[index]
            except IndexError:
                return MISSING
    else:
        def getter(obj):
            try:
                return tuple(obj[index] for index in indexes)
            except IndexError:
                return tuple(obj[index] if index < len(obj) else MISSING
                                for index in indexes)
    return getter

def sort_csv(csv_filename, sort_key_columns):
    with open(csv_filename, 'r', newline='') as f:
        data = [row for row in csv.reader(f)]

    data.sort(key=my_itemgetter(*sort_key_columns))

    with open(csv_filename, 'w', newline='') as f:
        csv.writer(f).writerows(data)

sort_csv('Huge_Complete_B2B_file_1_1.csv', [0, 171])