python将列表汇总到字典

时间:2018-07-04 01:13:02

标签: python list dictionary aggregate

我有一个看起来像这样的文件-

Col1      Col2     Key       Value
101       a        f1        abc
101       a        f2        def
102       a        f2        xyz
102       a        f3        fgh
103       b        f1        rst

,我需要如下输出文件:

{"Col1":101, "Col2":"a", "kvpairs":{"f1":"abc","f2":"def"}}
{"Col1":102, "Col2":"a", "kvpairs":{"f2":"xyz","f3":"fgh"}}
{"Col1":103, "Col2":"b", "kvpairs":{"f1":"rst"}}

我可以遍历该文件,将分组字段Col1和Col2的键值对组合到一个列表中,然后将其放入dict中,但是希望这样做有更多的Python方式。使用熊猫聚合可以回答一些问题,但是我找不到构建嵌套地图的整洁(高效的方式)。而且,源文件会很大,例如80m记录会压缩到结果文件中的8m。

我可以看到那些眼睛在发光:)

3 个答案:

答案 0 :(得分:0)

使用itertools.groupby()

from itertools import groupby

for ((c1,c2),items) in groupby(lines, key=lambda x: x[:2]):
    d = {"Col1": c1, "Col2:": c2, "kvpairs":dict(x[2:] for x in items)}
    print(d)

产生:

{'Col1': '101', 'Col2:': 'a', 'kvpairs': {'f1': 'abc', 'f2': 'def'}}
{'Col1': '102', 'Col2:': 'a', 'kvpairs': {'f2': 'xyz', 'f3': 'fgh'}}
{'Col1': '103', 'Col2:': 'b', 'kvpairs': {'f1': 'rst'}}

似乎您正在将某些值解析为文字-您可以使用int(c1)进行int操作,但是我不确定如何处理将"a"转换为{ {1}}。

(假设您有一个可迭代项的列表,可能来自a模块:)

csv

答案 1 :(得分:0)

data = []
for col1, col2, key, value in input:

    # look for an existing dict with col1 and col2
    for d in data:
        if d['col1'] == col1  and d['col2'] == col2:
            d['kvpairs'][key] = value
            break

    # no existing dict was found
    else:
        d.append({'col1': col1, 'col2': col2, 'kvpairs': {key: value}})

for d in data:
    print d

答案 2 :(得分:0)

groupby + agg + to_dict

df.groupby(["Col1", "Col2"])[["Key", "Value"]].agg(list).transform(lambda x: dict(zip(*x)),1).reset_index(name='kvpairs').to_dict('records')

[{'Col1': 101, 'Col2': 'a', 'kvpairs': {'f1': 'abc', 'f2': 'def'}},
 {'Col1': 102, 'Col2': 'a', 'kvpairs': {'f2': 'xyz', 'f3': 'fgh'}},
 {'Col1': 103, 'Col2': 'b', 'kvpairs': {'f1': 'rst'}}]

当然,df

z = io.StringIO("""Col1      Col2     Key       Value
101       a        f1        abc
101       a        f2        def
102       a        f2        xyz
102       a        f3        fgh
103       b        f1        rst""")

df = pd.read_table(z,delim_whitespace=True)

说明

首先,您aggregate使用list

df.groupby(["Col1", "Col2"])[["Key", "Value"]].agg(list)

              Key           Value
Col1    Col2        
101     a    [f1, f2]     [abc, def]
102     a    [f2, f3]     [xyz, fgh]
103     b    [f1]         [rst]

然后transform将此输出输出到字典并完全重命名轴

.transform(lambda x: dict(zip(*x)),1).reset_index(name='kvpairs')

    Col1    Col2    kvpairs
0   101     a       {'f1': 'abc', 'f2': 'def'}
1   102     a       {'f2': 'xyz', 'f3': 'fgh'}
2   103     b       {'f1': 'rst'}

最后,使用to_dict('records')来获取字典列表

.to_dict('records')
[{'Col1': 101, 'Col2': 'a', 'kvpairs': {'f1': 'abc', 'f2': 'def'}},
 {'Col1': 102, 'Col2': 'a', 'kvpairs': {'f2': 'xyz', 'f3': 'fgh'}},
 {'Col1': 103, 'Col2': 'b', 'kvpairs': {'f1': 'rst'}}]