Преобразование среднего значения значений списка 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, список всегда меняется.
- Python: повторение на нескольких уровнях
- Ссылка на список из списка списков
- Итерация через рамку данных pandas и вставка новых значений в пустой столбец
- Быстрый способ отклонения списка в Python
- Очередь с итерацией 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,[]))
- проблема с новыми строками, когда я использую toprettyxml ()
- Как адаптировать или изменить размер прямоугольника внутри объекта, не включая (или с несколькими числами) фоновых пикселей?
- Многомерный массив Python – добавление дополнительных значений в начало и конец каждой строки
- Время икры иглы увеличивается экспоненциально при использовании соединения
- Как продвигать итерацию внутри строк таблицы итератора
- Подход Pandaic к итерации над файловой рамкой
- PyInstaller TypeError: итерация по нескольким
- Замена для … если итерация массива
- Python + MongoDB – слишком медленная итерация курсора
- Сделать рекурсивную функцию for для циклов и если инструкции в итеративной функции
- Как добавить столбец идентификатора для идентификации таблиц read_html ()?