在Python中处理CSV

时间:2014-06-28 10:41:02

标签: python csv jython

我这里有一个CSV文件,其中包含我们工作的某些服务器的一系列属性和值。

这是一个简短的样本:

Asset_ID     PropSVC     PropSVN     PropTSC     PropTSN
------------------------------------------------------------
A0001        SVC001      N032        TSC538      TS_BLAH
A0002        SVC002      N384        TSC002      TS_BLAH
A0006        SVC1223     N456        TSC002      TN_foo
A0006        SVC1223     N456        TSC004      T_Bar

正如您所看到的,有一些服务器(由其资产ID索引)具有重复条目,因此具有不同的属性。有些服务器可能不会在相邻的行中重复,而是遍布整个文件,但我不认为这会造成问题。 我想做的是使用Jython 2.7从这里提取数据并创建如下文件:

Asset_ID     Property     Value
----------------------------------
A0001        PropSVC     SVC001
A0001        PropSVN     N032
A0001        PropTSC     TSC538
A0001        PropTSN     TS_Blah
A0002        PropSVC     SVC002
A0002        PropSVN     N384
A0002        PropTSC     TSC002
A0002        PropTSN     TS_Blah
A0006        PropSVC     SVC1223
A0006        PropSVN     N456
A0006        PropTSC     TSC002, TSC004
A0006        PropTSN     TN_foo, T_Bar

这基本上是每个服务器属性及其值或值的列表(如果多于一个且它们不相同)。这样,文件变得更小,更容易用作我们将要使用的另一个软件的输入。

是否有任何功能或方法可以相对快速的方式完成此任务?

1 个答案:

答案 0 :(得分:1)

首先,假设您的CSV文件名为data.csv,以制表符分隔,并包含:

A0001        SVC001      N032        TSC538      TS_BLAH
A0002        SVC002      N384        TSC002      TS_BLAH
A0006        SVC1223     N456        TSC002      TN_foo
A0006        SVC1223     N456        TSC004      T_Bar

确定列:

  • Asset_ID 0
  • PropSVC 1
  • PropSVN 2
  • PropTSC 3
  • PropTSN 4

将这些记录为:

ID_COLUMN = 0 # Asset_ID
PROP_COLUMNS = [
    ('PropSVC', 1),
    ('PropSVN', 2),
    ('PropTSC', 3),
    ('PropTSN', 4),
]

我假设您的数据是制表符分隔的,因此您可以使用以下方法解析它:

import csv
with open('data.csv', 'rb') as fh:
    reader = csv.reader(fh, delimiter='\t')

如果没有任何处理,解析时数据将如下所示:

['A0001', 'SVC001', 'N032', 'TSC538', 'TS_BLAH']
['A0002', 'SVC002', 'N384', 'TSC002', 'TS_BLAH']
['A0006', 'SVC1223', 'N456', 'TSC002', 'TN_foo']
['A0006', 'SVC1223', 'N456', 'TSC004', 'T_Bar']

现在,您希望按资产ID和属性聚合属性值:

import collections
data = collections.defaultdict(set)
for row in reader:
    asset_id = row[ID_COLUMN]
    for prop, column in PROP_COLUMNS:
        prop_value = row[column]
        data[(asset_id, prop)].add(prop_value)

汇总的data现在看起来像是:

{('A0001', 'PropSVC'): set(['SVC001']),
 ('A0001', 'PropSVN'): set(['N032']),
 ('A0001', 'PropTSC'): set(['TSC538']),
 ('A0001', 'PropTSN'): set(['TS_BLAH']),
 ('A0002', 'PropSVC'): set(['SVC002']),
 ('A0002', 'PropSVN'): set(['N384']),
 ('A0002', 'PropTSC'): set(['TSC002']),
 ('A0002', 'PropTSN'): set(['TS_BLAH']),
 ('A0006', 'PropSVC'): set(['SVC1223']),
 ('A0006', 'PropSVN'): set(['N456']),
 ('A0006', 'PropTSC'): set(['TSC002', 'TSC004']),
 ('A0006', 'PropTSN'): set(['TN_foo', 'T_Bar'])}

现在让我们将这些数据保存到output.csv

with open('output.csv', 'wb') as fh:
    writer = csv.writer(fh, delimiter='\t')
    for (asset_id, prop), prop_values in data.iteritems():
        prop_values = ", ".join(prop_values)
        writer.writerow([asset_id, prop, prop_values])

这将创建包含以下内容的制表符分隔文件output.csv

A0001     PropSVC     SVC001
A0001     PropSVN     N032
A0001     PropTSC     TSC538
A0001     PropTSN     TS_BLAH
A0002     PropSVC     SVC002
A0002     PropSVN     N384
A0002     PropTSC     TSC002
A0002     PropTSN     TS_BLAH
A0006     PropSVC     SVC1223
A0006     PropSVN     N456
A0006     PropTSC     TSC002, TSC004
A0006     PropTSN     TN_foo, T_Bar

注意:如果您运行的是Jython 2.5,则需要将from __future__ import with_statement添加到脚本顶部,或将所有with open(...) as fh替换为fh = open(...)