将列表附加到匹配键值的值

时间:2015-11-14 08:57:17

标签: python csv dictionary

我的csv中有以下两行:

0000001,0,-94.8,28
0000001,6,-95.4,28

假设source_id 0000001对应event_id 123456,这就是以下代码行正在做的事情:

source_id = row[0].lstrip("0")
if source_id in sourceid_eventid_dict:
    event_id = sourceid_eventid_dict[source_id]

在阅读了两行csv后,我需要获得以下字典集。

{123456: [[-94.8, 28], [-95.4, 28]}

我目前的代码如下:

model_dev_coordinate_dict = dict()    
# create dict of eventid, coordinates from model dev csv
with open(model_dev_file, newline='') as f:
    reader = csv.reader(f)
    for row in reader:
        source_id = row[0].lstrip("0")
        if source_id in sourceid_eventid_dict:
            event_id = sourceid_eventid_dict[source_id]
            model_dev_coordinate_dict.setdefault(event_id, []).append([row[2], row[3]])

我的代码每次都创建一个新的键值对,而不是使用现有的键将新列表附加到现有值。

2 个答案:

答案 0 :(得分:4)

  

在阅读了两行csv后,我需要获取以下字典集。   {123456: [[-94.8, 28], [-95.4, 28]}

为此,您可以使用csv模块解析输入slicing以将 source_id 与每行上的数据分开,一个将 source_id 转换为 event_id 的简单字典,以及带有 list.append dict.setdefault()来处理数据聚合。

import csv
import pprint

s = '''\
0000001,0,-94.8,28
0000001,6,-95.4,28
0000002,7,-97.6,29
'''.splitlines()

event_map = {'0000001': '123456', '0000002': '789012'}

groupdict = {}
for row in csv.reader(s):
    source_id = row[0]
    event_id = event_map[source_id]
    data = row[1:]
    groupdict.setdefault(event_id, []).append(data)
pprint.pprint(groupdict)

以上代码输出:

{'123456': [['0', '-94.8', '28'], ['6', '-95.4', '28']],
 '789012': [['7', '-97.6', '29']]}

答案 1 :(得分:1)

另一种方法是使用pandas

以下是整个代码:

import io
import pandas as pd

fobj = io.StringIO("""
0000001,0,-94.8,28
0000001,6,-95.4,28
0000002,7,-97.6,29
""")

event_map = {'0000001': '123456', '0000002': '789012'}

df = pd.read_csv(fobj, header=None, index_col=0, 
                 converters={0: lambda k: event_map[k]})
res = {k: df.ix[k].values.tolist() for k in df.index.unique()}

现在步骤。

从样本数据开始:

fobj = io.StringIO("""
0000001,0,-94.8,28
0000001,6,-95.4,28
0000002,7,-97.6,29
""")
event_map = {'0000001': '123456', '0000002': '789012'}

进口:

import io
import pandas as pd

阅读成为一个单行:

df = pd.read_csv(fobj, header=None, index_col=0, 
                 converters={0: lambda k: event_map[k]})

数据框如下所示:

print(df)

        1     2   3
0                  
123456  0 -94.8  28
123456  6 -95.4  28
789012  7 -97.6  29

使用.ix[]访问一个事件:

print(df.ix['123456'])
        1     2   3
0                  
123456  0 -94.8  28
123456  6 -95.4  28

您还可以将条目转换为列表:

>>> df.ix['123456'].values.tolist()
[[0.0, -94.8, 28.0], [6.0, -95.4, 28.0]]

当然,您可以将结果转换为字典:

>>> {k: df.ix[k].values.tolist() for k in df.index.unique()}
{123456: [[0.0, -94.8, 28.0], [6.0, -95.4, 28.0]], 
 789012: [7.0, -97.6, 29.0]}