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的连接数
有没有解决方案?
答案 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