Преобразование среднего значения значений списка Python в другой список

У меня есть списки, подобные этому.

list = [["Joe", 5, 7], ["Joe", 6, 9], ["Mike", 1,4], ["Joe", 7,4], ["Mike", 5,7]] 

Как преобразовать этот список в список:

 list2 = [["Joe", 6.00, 6.66], ["Mike", 3.00, 5.50]] 

list2 [0] [1] и list2 [1] [1] – это средние значения из первого списка со специальными людьми (6.00 исходит из (list[0][1]+list[1][1]+list[3][1])/3

Я должен использовать итерацию следующим образом:

 for i in range(len(list)): ... 

или что-то типа того? Поскольку я импортирую список из SQLite, список всегда меняется.

5 Solutions collect form web for “Преобразование среднего значения значений списка Python в другой список”

Поскольку вы говорите, что импортируете список из sqlite, вам может быть интересно использовать существующий пакет обработки данных, а не перекладывать свою собственную функцию по функциям. Например, в pandas вы можете загрузить данные в DataFrame :

 >>> df = pd.DataFrame(yourlist) >>> df 0 1 2 0 Joe 5 7 1 Joe 6 9 2 Mike 1 4 3 Joe 7 4 4 Mike 5 7 [5 rows x 3 columns] >>> df.groupby(0).mean() 1 2 0 Joe 6 6.666667 Mike 3 5.500000 [2 rows x 2 columns] 

Теперь использование pandas будет значительным переполнением для проблемы в изоляции, но если вы вытаскиваете данные из базы данных, вы, вероятно, захотите сделать несколько вещей с данными.

Это работает для любого количества значений, которые вы суммируете (в вашем случае два):

Python 3

 from collections import defaultdict rows = [["Joe", 5, 7], ["Joe", 6, 9], ["Mike", 1,4], ["Joe", 7,4], ["Mike", 5,7]] d = defaultdict(list) for k, *v in rows: d[k].append(v) averages = [[k] + [sum(x) / len(v) for x in zip(*v)] for k, v in d.items()] print(averages) 

Python 2

Замените items() на iteritems() , добавьте float вокруг sum(x) , используйте print с пробелом, а не parens, и измените цикл for на

 for row in rows: d[row[0]].append(row[1:]) 

(Python 3 уверен, хорошо.)


объяснение

defaultdict и for цикла создают карту из имени в список значений.

 {'Mike': [[1, 4], [5, 7]], 'Joe': [[5, 7], [6, 9], [7, 4]]} 

k, v in d.items() итерации по каждому имени и списку списков.

zip(*v) принимает что-то вроде [[5, 7], [6, 9], [7, 4]] и превращает его в [[5, 6, 7], [7, 9, 4]] . Затем мы суммируем их и делим на количество исходных списков.

Мы добавляем [k] и этот список средних значений для получения списка, например ['Joe', 6.0, 6.67] .

Кстати, если это происходит из базы данных, считаете ли вы, что там происходит агрегация?

Что-то вроде этого:

 >>> from collections import OrderedDict >>> lis = [["Joe", 5, 7], ["Joe", 6, 9], ["Mike", 1,4], ["Joe", 7,4], ["Mike", 5,7]] >>> d = OrderedDict() >>> for item in lis: ... d.setdefault(item[0], []).append(item[1:]) 

Теперь d содержит:

 >>> d OrderedDict([('Joe', [[5, 7], [6, 9], [7, 4]]), ('Mike', [[1, 4], [5, 7]])]) 

Упорядоченные уникальные ключи, которые когда-либо видели, здесь сохранились, поскольку мы использовали здесь OrderedDict .

Теперь мы можем перебирать этот словарь и получать среднее значение столбцов для каждого ключа. zip with * позволяет нам легко переносить список из списка:

 >>> zip(*[[5, 7], [6, 9], [7, 4]]) [(5, 6, 7), (7, 9, 4)] >>> 

Заключительный список:

 >>> [[k] + [sum(x)/float(len(x)) for x in zip(*v)] for k, v in d.items()] [['Joe', 6.0, 6.666666666666667], ['Mike', 3.0, 5.5]] 

Вы можете удалить float вызов в Python3. И если порядок имен «Joe», «Mike» не имеет значения в выходном списке, тогда вы можете просто использовать нормальный dict с dict.setdefault или use collections.defaultdict .

Использование itertools.groupby :

 >>> from itertools import groupby >>> data = [["Joe", 5, 7], ["Joe", 6, 9], ["Mike", 1, 4], ["Joe", 7, 4], ["Mike", 5, 7]] >>> data.sort() >>> result = [] >>> for _, groups in groupby(d, lambda x: x[0]): it = iter(zip(*groups)) row = [next(it)[0]] for values in it: row.append(sum(values) / len(values)) result.append(row) >>> result [['Joe', 6.0, 6.666666666666667], ['Mike', 3.0, 5.5]] 

Альтернативное решение. Он немного сложный, но один вкладыш без импорта.

 map(lambda x : [x[0],float(x[1])/x[3],float(x[2])/x[3]],reduce(lambda x,y : x[0:(len(x)-1)] + [[x[-1][0],x[-1][1]+y[1],x[-1][2]+y[2],x[-1][3]+1]] if ((y[0] == x[-1][0]) if (len(x)>0) else False) else x + [[y[0],y[1],y[2],1]] ,arr,[])) 
  • Как сделать значок в QMenu больше (PyQt)?
  • Как заставить команду python3 запускать Python 3.6 вместо 3.5?
  • Как извлечь элементы подписок в однострочном понимании в python?
  • Перетаскивание в Tkinter?
  • Как написать Python 2.x как можно более совместимым с Python 3.x?
  • Утечка памяти при отбрасывании изображения в Python
  • Отсутствует модуль запросов "py2exe"
  • Запустите HTML-код в браузере (который создается BeautifulSoup) прямо из Python
  • Python - лучший язык программирования в мире.