简体   繁体   中英

Python, clustered two-column count

I have the following list:

a = [['A','R.1',1],['B','R.2',1],['B','R.2',2],['C','R.2',3],
     ['C','C.1',4],['C','C.1',5],['A','C.1',8],['B','C.1',9],
     ['B','C.1',1],['A','R.3',2],['C','R.1',3],['A','R.2',4],
     ['C','R.1',5],['A','R.1',1],['C','R.2',5],['A','R.1',8]]

I need to somehow group it to generate the following result:

[['A', 'C.1', 1],
 ['A', 'R.1', 3],
 ['A', 'R.2', 1],
 ['A', 'R.3', 1],
 ['B', 'C.1', 2],
 ['B', 'R.2', 2],
 ['C', 'C.1', 2],
 ['C', 'R.1', 2],
 ['C', 'R.2', 2]]

Where the third column is count of rows where the first and second columns match. From the original list the value of the third column is negligible.

I have already tried via "for" nested and "list comprehension", but I have not been able to come up with any results.

Does anyone have any clue how I can resolve this?

With collections.defaultdict object:

import collections

a = [['A','R.1',1],['B','R.2',1],['B','R.2',2],['C','R.2',3],
     ['C','C.1',4],['C','C.1',5],['A','C.1',8],['B','C.1',9],
     ['B','C.1',1],['A','R.3',2],['C','R.1',3],['A','R.2',4],
     ['C','R.1',5],['A','R.1',1],['C','R.2',5],['A','R.1',8]]

d = collections.defaultdict(int)
for l in a:
    d[(l[0],l[1])] += 1

result = [list(k)+[v] for k,v in sorted(d.items())]
print(result)

The output:

[['A', 'C.1', 1], ['A', 'R.1', 3], ['A', 'R.2', 1], ['A', 'R.3', 1], ['B', 'C.1', 2], ['B', 'R.2', 2], ['C', 'C.1', 2], ['C', 'R.1', 2], ['C', 'R.2', 2]]

Just for "pretty" print:

import pprint
...
pprint.pprint(result)

The output:

[['A', 'C.1', 1],
 ['A', 'R.1', 3],
 ['A', 'R.2', 1],
 ['A', 'R.3', 1],
 ['B', 'C.1', 2],
 ['B', 'R.2', 2],
 ['C', 'C.1', 2],
 ['C', 'R.1', 2],
 ['C', 'R.2', 2]]

Similar to @RomanPerekhrest, I used a Counter :

from collections import Counter

a = [['A','R.1',1],['B','R.2',1],['B','R.2',2],['C','R.2',3],
     ['C','C.1',4],['C','C.1',5],['A','C.1',8],['B','C.1',9],
     ['B','C.1',1],['A','R.3',2],['C','R.1',3],['A','R.2',4],
     ['C','R.1',5],['A','R.1',1],['C','R.2',5],['A','R.1',8]]

def transform(table):
    c = Counter(map(lambda c: tuple(c[:-1]), table))
    return sorted(map(lambda p: list(p[0]) + [p[1]], c.items()))

print(transform(a))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM