2016-03-09 4 views
0

У меня есть файл CSV, который имеет данные:Сортировка и добавить элементы списка на основе общего атрибута

California C1  A   1 
.   .  .   . 
.   .  .   . 
.   .  .   . 
.   .  .   . 

так выглядит это, если смотреть в Python:

['California','C1','A',1] 
['Hawaii','H1','B',2] 
['California','C1','A',3] 
['California','C2','A',4] 
['Hawaii','H1','A',5] 
['Hawaii','H1','A',6] 
['California','C1','B',7] 
['Hawaii','H2','B',8] 
['California','C1',B',9] 
['Hawaii','H2','A',10] 

I хотел бы иметь выход как верхний 1 каждого списка, а именно:

['California','C1',B',16] 
['California','C2','A',4] 
['Hawaii','H1','A',11] 
['Hawaii','H2','A',10] 

в основном. Я хотел бы суммировать последнюю часть списка на основе первых 3 атрибутов списка, а затем вернуть верхнюю часть 1, учитывая три атрибута. Мой код выглядит следующим образом:

import collections 

def top_1(list): 
    ranking = collections.Counter(list) 
    return [elem for elem, _ in sorted(counts.most_common(),key=lambda x:(‐x[1], x[0])) 
    [:1]] 
csvReader =csv.reader(open('data.csv','rb'), delimiter=',', quotechar='"') 
    data = [] 
    for i in range(int(line[3]): 
     data.append([line[0], line[1], line[2])) 
    print top_1(data) 

но он не дает мне выход, который я ожидаю.

+1

ваши данные действительно нравится в вашем входе или что анализируемые данные как список? – Kordi

+2

Проверьте http://stackoverflow.com/help/mcve и попробуйте привести пример, который другие могут легко выполнить без необходимости переформатировать ваши данные и ваш код. – roadrunner66

+0

Почему вы используете 'return' перед созданием * csvReader *? – styvane

ответ

0

Код

Вы можете использовать itertools GroupBy и CSV для чтения. Тогда это всего лишь два лайнера. Разделите линию на 4 строки для лучшей читаемости.

import itertools 
import operator 
import csv 

inputList = list(csv.reader(open('data.csv','rb'), delimiter=',', quotechar="'")) 
groupedList = [x[0:3] + (sum(int(z[3]) for z in y),) for (x,y) in 
       itertools.groupby(sorted(inputList, key=operator.itemgetter(0, 1, 2)), 
            key=operator.itemgetter(0, 1, 2))] 

print groupedList 

Объяснение

Читайте CSV и конвертировать его в список. Сортируйте список после первых 3 столбцов, затем группируйте их после этих первых трех столбцов. В качестве возвращаемого значения берутся первые 3 столбца, а затем суммируются по сгруппированному результату столбца 4, переданного в int.

Входной data.csv

'California','C1','A',1 
'Hawaii','H1','B',2 
'California','C1','A',3 
'California','C2','A',4 
'Hawaii','H1','A',5 
'Hawaii','H1','A',6 
'California','C1','B',7 
'Hawaii','H2','B',8 
'California','C1','B',9 
'Hawaii','H2','A',10 

Обратите внимание на вашем входе есть недостающий ' в 'C1',B',9

Выход

[('California', 'C1', 'A', 4), 
('California', 'C1', 'B', 16), 
('California', 'C2', 'A', 4), 
('Hawaii', 'H1', 'A', 11), 
('Hawaii', 'H1', 'B', 2), 
('Hawaii', 'H2', 'A', 10), 
('Hawaii', 'H2', 'B', 8)] 
+0

@ DaoWen Спасибо за уведомление. Никогда бы этого не делал в моем собственном коде, но для примеров. – Kordi

0

Я думаю, что вы хотите сделать, это сумма последнего столбца для каждого из первых значений первого трех столбца.

Попробуйте этот подход:

import csv 
from collections import defaultdict 

results = defaultdict(int) 

with open('somefile.csv') as f: 
    reader = csv.reader(f) 
    for row in reader: 
     results[tuple(row[:-1])] += int(row[-1]) 

print(results) 
1

Следующий подход должен дать вам желаемый результат:

from collections import Counter  
from itertools import groupby, islice 
import csv 

counts = Counter() 

with open('data.csv', 'rb') as f_input: 
    csv_input = csv.reader(f_input) 

    for row in csv_input: 
     counts.update({tuple(row[:3]) : int(row[3])}) 

output = []   
for k, g in groupby(sorted(counts.iteritems(), key=lambda x:(x[0][0], -x[1])), lambda x:x[0][0]): 
    output.extend([list(e[0]) + [e[1]] for e in islice(g, 0, 2)]) 

print output 

Это будет дисплей:

[['California', 'C1', 'B', 16], ['California', 'C2', 'A', 4], ['Hawaii', 'H1', 'A', 11], ['Hawaii', 'H2', 'A', 10]] 
Смежные вопросы