按类别为每个日期排序数据

时间:2013-10-12 22:23:38

标签: python python-2.7 csv match grouping

我有一些数据集,我需要能够按uniquenameclass为每个日期分组。在下面的示例数据中,我使用了UniqueNameClass1UniqueNameClass3等,但实际上它们只是文本字符串。所以我需要能够做的是循环选择一个当时日期相同的组的csv,然后通过UniqueNameClass在该日期组内进行分组。如果这很难理解,希望这个例子可以解释我遇到的问题:

原始数据

text,text,text,11/03/12,text,text,text,UniqueNameClass1,text,text
text,text,text,11/03/12,text,text,text,UniqueNameClass2,text,text
text,text,text,11/03/12,text,text,text,UniqueNameClass4,text,text
text,text,text,11/03/12,text,text,text,UniqueNameClass3,text,text
text,text,text,11/03/12,text,text,text,UniqueNameClass1,text,text
text,text,text,11/03/12,text,text,text,UniqueNameClass2,text,text
text,text,text,11/03/12,text,text,text,UniqueNameClass5,text,text
text,text,text,11/03/12,text,text,text,UniqueNameClass1,text,text
text,text,text,11/03/12,text,text,text,UniqueNameClass1,text,text
text,text,text,12/03/12,text,text,text,UniqueNameClass5,text,text
text,text,text,12/03/12,text,text,text,UniqueNameClass3,text,text
text,text,text,12/03/12,text,text,text,UniqueNameClass4,text,text
text,text,text,12/03/12,text,text,text,UniqueNameClass5,text,text
text,text,text,12/03/12,text,text,text,UniqueNameClass5,text,text
text,text,text,12/03/12,text,text,text,UniqueNameClass3,text,text
text,text,text,12/03/12,text,text,text,UniqueNameClass5,text,text
text,text,text,12/03/12,text,text,text,UniqueNameClass4,text,text
text,text,text,12/03/12,text,text,text,UniqueNameClass4,text,text
text,text,text,13/03/12,text,text,text,UniqueNameClass5,text,text
text,text,text,13/03/12,text,text,text,UniqueNameClass4,text,text
text,text,text,13/03/12,text,text,text,UniqueNameClass2,text,text
text,text,text,13/03/12,text,text,text,UniqueNameClass1,text,text 
text,text,text,13/03/12,text,text,text,UniqueNameClass3,text,text
text,text,text,13/03/12,text,text,text,UniqueNameClass2,text,text
text,text,text,13/03/12,text,text,text,UniqueNameClass2,text,text

按日期排序的数据,然后按UniqueNameClass

分组
text,text,text,11/03/12,text,text,text,UniqueNameClass1,text,text
text,text,text,11/03/12,text,text,text,UniqueNameClass1,text,text
text,text,text,11/03/12,text,text,text,UniqueNameClass1,text,text
text,text,text,11/03/12,text,text,text,UniqueNameClass1,text,text
text,text,text,11/03/12,text,text,text,UniqueNameClass2,text,text
text,text,text,11/03/12,text,text,text,UniqueNameClass2,text,text
text,text,text,11/03/12,text,text,text,UniqueNameClass4,text,text
text,text,text,11/03/12,text,text,text,UniqueNameClass3,text,text
text,text,text,11/03/12,text,text,text,UniqueNameClass5,text,text
text,text,text,12/03/12,text,text,text,UniqueNameClass3,text,text
text,text,text,12/03/12,text,text,text,UniqueNameClass3,text,text
text,text,text,12/03/12,text,text,text,UniqueNameClass4,text,text
text,text,text,12/03/12,text,text,text,UniqueNameClass4,text,text
text,text,text,12/03/12,text,text,text,UniqueNameClass4,text,text
text,text,text,12/03/12,text,text,text,UniqueNameClass5,text,text
text,text,text,12/03/12,text,text,text,UniqueNameClass5,text,text
text,text,text,12/03/12,text,text,text,UniqueNameClass5,text,text
text,text,text,12/03/12,text,text,text,UniqueNameClass5,text,text
text,text,text,13/03/12,text,text,text,UniqueNameClass1,text,text
text,text,text,13/03/12,text,text,text,UniqueNameClass2,text,text
text,text,text,13/03/12,text,text,text,UniqueNameClass2,text,text
text,text,text,13/03/12,text,text,text,UniqueNameClass2,text,text
text,text,text,13/03/12,text,text,text,UniqueNameClass3,text,text
text,text,text,13/03/12,text,text,text,UniqueNameClass4,text,text
text,text,text,13/03/12,text,text,text,UniqueNameClass5,text,text

因此,UniqueNameClass只能将同一日期的数据组合在一起。我知道在这个例子中,我按时间顺序排列组,这对组的顺序无关紧要,只是在给定日期每组的每一行都是彼此相邻的。

修改

我试图运行phihag提供的代码,有很多不同的方法,但是我尝试的所有方法都产生了回溯:

File "C:\RawDataeDataTest.py", line 6, in <module>
    data = list(csv.reader(io.StringIO('RawDataeDataTest.csv')))
TypeError: initial_value must be unicode or None, not str

我认为根据提供的代码和提供的评论工作的代码是:

import csv
import io

data = list(csv.reader(io.StringIO('RawDataeDataTest.csv')))
data.sort(key=lambda row: (row[3], row[7]))
print(u'\n'.join(u','.join(row) for row in data))

import csv
import io

data = list(csv.reader('RawDataeDataTest.csv'))
data.sort(key=lambda row: (row[3], row[7]))
print(u'\n'.join(u','.join(row) for row in data))

对于后者,我实际上得到了不同的追溯:

Traceback (most recent call last):
  File "C:\RawDataeDataTest.py", line 7, in <module>
    data.sort(key=lambda row: (row[3], row[7]))
  File "C:\RawDataeDataTest.py", line 7, in <lambda>
    data.sort(key=lambda row: (row[3], row[7]))
IndexError: list index out of range

1 个答案:

答案 0 :(得分:4)

只需提供key functionsort即可提取正确的字段,如下所示:

import csv
import io

s = u'''text,text,text,11/03/12,text,text,text,UniqueNameClass1,text,text
text,text,text,11/03/12,text,text,text,UniqueNameClass2,text,text
text,text,text,10/03/12,text,text,text,UniqueNameClass3,text,text
text,text,text,12/03/12,text,text,text,UniqueNameClass1,text,text
text,text,text,10/03/12,text,text,text,UniqueNameClass2,text,text
text,text,text,10/03/12,text,text,text,UniqueNameClass5,text,text'''

data = list(csv.reader(io.StringIO(s)))
data.sort(key=lambda row: (row[3], row[7]))
print(u'\n'.join(u','.join(row) for row in data))

要从文件而不是常量字符串中读取,只需传入opened文件:

with open('RawDataeDataTest.csv', 'rb') as csvf:
    data = list(csv.reader(csvf))
data.sort(key=lambda row: (row[3], row[7]))
print(u'\n'.join(u','.join(row) for row in data))

如果要将结果再次存储在同一文件中,请先将其写入临时文件,然后以原子方式移动它:

import csv
import functools
import io
import tempfile
import os
import sys

filename = 'RawDataeDataTest.csv'

if sys.version_info >= (3, 0):
    open_args = lambda mode: {'encoding': 'utf-8', 'mode': mode}
else:
    open_args = lambda mode: {'mode': mode + 'b'}

with io.open(filename, **open_args('r')) as csvf:
    data = list(csv.reader(csvf))
data.sort(key=lambda row: (row[3], row[7]))


with tempfile.NamedTemporaryFile(dir=os.path.dirname(filename), delete=False,
                                 **open_args('w')) as of:
    try:
        csv.writer(of).writerows(data)
        of.flush()
    except:
        os.unlink(of.name)
        raise

    try:
        os.replace(of.name, filename)
    except AttributeError:  # Python < 3.3
        if os.name == 'nt':
            os.remove(filename)
        os.rename(of.name, filename)