python中来自csv文件的数据累积

时间:2018-01-24 12:39:14

标签: python csv

out_gate,in_gate,num_connection
a,b,1
a,b,3
b,a,2
b,c,4
c,a,5
c,b,5
c,b,3
c,a,4
上面显示的是一个示例csv文件。 首先,我的最终目标是编译结果成为关于门之间连接数的表格,如下所示:

  a b c 
a 0 4 0 
b 2 0 4 
c 9 8 0 

现在我完成了第一列的列表(out_gate) 像这样; listfile = ['a','b','c']并尝试将每个数据(a,b,c)逐个匹配到in_gate 所以,例如当out_gate' c' - > in_gate' b',连接数为8和 ' C' - >'一个'变成了9。

我可以将out_blk和in_blk与其连接数匹配,但很难累积每个out_gate的连接数

有没有解决方案?

4 个答案:

答案 0 :(得分:1)

在纯Python中,您应该查看输入的csv模块和收集总计的collections.defaultdict

from csv import reader
from collections import defaultdict

d = defaultdict(lambda: defaultdict(int))
with open('file.csv') as f:
    r = reader(f)
    next(r)  # skip headers
    for row in r:
        if len(row) >= 3:
            x, y, count = row
            d[x][y] += int(count)

keys = sorted(d)
for x in keys:
    print(' '.join(str(d[x][y]) for y in keys))

0 4 0
2 0 4
9 8 0

答案 1 :(得分:1)

如果对大量数据执行此操作,则应该绝对检查numpy和pandas,它们都比原生python更有效,更自然地处理表。

如果您现在只需要解决方案,可以使用collections.defaultdict在纯python中直接进行累积:

from collections import defaultdict

con = defaultdict(int)
for count, line in enumerate(connections):
    if count == 0:
        continue
    in_gate, out_gate, number = line.split(',')
    con[f"{in_gate}->{out_gate}"] += int(number)

现在您可以通过以下方式访问条目:

print(con['a->b'])
>> 4
print(con['a->c'])
>> 0

答案 2 :(得分:1)

如果您不想诉诸逐行读者和默认用户,这是pandas.pivot_table的单行高级答案。

import pandas as pd

df = pd.DataFrame([['a', 'b', 1], ['a', 'b', 3], ['b', 'a', 2], ['b', 'c', 4],
                   ['c', 'a', 5], ['c', 'b', 5], ['c', 'b', 3], ['c', 'a', 4]],
                  columns=['out_gate', 'in_gate', 'num_connection'])

pd.pivot_table(df, index='out_gate', columns='in_gate', values='num_connection', aggfunc='sum').fillna(0)

答案 3 :(得分:0)

您可以使用itertools.groupby

import csv
import itertools
data = list(csv.reader(open('filename.csv')))
new_data = [b+[int(a)] for *b, a in data]
final_data = {tuple(a):sum(map(lambda x:x[-1], list(b))) for a, b in itertools.groupby(sorted(new_data, key=lambda x:x[:2]), key=lambda x:x[:2])}
letters = sorted(set([i for b in final_data.keys() for i in b]))
matrix = '\n'.join([' '.join(map(str, [final_data.get((b, i), 0) for i in letters])) for b in letters])

输出:

0 4 0
2 0 4
9 8 0