Как сгруппировать вложенный список по первому элементу вложенного списка? - PullRequest
0 голосов
/ 13 апреля 2019

У меня есть список данных с именем, годом, суммой и результатом.Я хочу рассчитать общую сумму выигрыша и общий убыток каждого года.(Желательно использовать функции списка для начинающих) Спасибо

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

>>> my_list = [ ['a', '2013', '10.22', 'won'], ['b', '2012', '11.23', 'won'], ['c', '2013', '12.62', 'lost']]
>>> headers = ['name', 'year', 'amount', 'result']
>>> my_dict = {k: [x [i] for x in my_list] for i, k in enumerate(headers)}

Какполучить общую сумму выигрыша и потерянную сумму

Я ожидаю, что возврат будет в формате

Year    Total Won  Total Lost
2012    11.23      0
2013    10.22      12.62

Ответы [ 3 ]

1 голос
/ 13 апреля 2019

Вместо словарного понимания (ваш подход) я бы предложил написать некоторый код. Это решение делает то, что вы ищете.

from collections import defaultdict
d = defaultdict(dict)

my_list = [ ['a', '2013', '10.22', 'won'], ['b', '2012', '11.23', 'won'], ['c', '2013', '12.62', 'lost']]

for rec in my_list:
    if rec[3] in d[rec[1]]:
        d[rec[1]][rec[3]] += float(rec[2])
    else:
        d[rec[1]][rec[3]] = float(rec[2])

print('Year', "won", "    lost")
for year in sorted(d):
    print(year, '\t'.join([str(d[year].get('won', '0')), \
                           str(d[year].get('lost', '0'))]))

Это печатает:

Year won     lost
2012 11.23  0
2013 10.22  12.62
1 голос
/ 13 апреля 2019

Предполагая, что ваш ожидаемый результат на 2012 год является опечаткой (и вы хотели показать 11.23 как общее количество выигранных, как указано в вашем наборе данных), вы можете использовать itertools.groupby и sum для суммирования общего выигрыша / проигрыша за год.При необходимости вы можете изменить формат вывода, но это должно помочь вам.

from itertools import groupby
from operator import itemgetter

results = [['a', '2013', '10.22', 'won'], ['b', '2012', '11.23', 'won'], ['c', '2013', '12.62', 'lost']]
for year, values in groupby(sorted(results, key=itemgetter(1)), key=itemgetter(1)):
    values = list(values)
    won = sum(float(v[2]) for v in values if v[3] == 'won')
    lost = sum(float(v[2]) for v in values if v[3] == 'lost')
    print(f'Year: {year} Total Won: {won} Total Lost: {lost}')

# Year: 2012 Total Won: 11.23 Total Lost: 0
# Year: 2013 Total Won: 10.22 Total Lost: 12.62
1 голос
/ 13 апреля 2019

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

import pandas as pd

headers = ['name', 'year', 'amount', 'result']
my_list = [ ['a', '2013', '10.22', 'won'],
            ['b', '2012', '11.23', 'won'], 
            ['c', '2013', '12.62', 'lost']]

df = pd.DataFrame(my_list, columns=headers)
df.amount = pd.to_numeric(df.amount) # makes amount numeric

df2 = pd.pivot_table(df, index='year', columns='result', values='amount', aggfunc=sum)
# result   lost    won
# year                
# 2012      NaN  11.23
# 2013    12.62  10.22

Чтобы изменить NaN на 0

df2.fillna(0, inplace=True)

Оттуда вы можете повеселиться и сделать несколькоболее хорошие вещи, такие как подсчитать чистое изменение.

df2['net'] = df2.won - df2.lost
# result   lost    won    net
# year                       
# 2012     0.00  11.23  11.23
# 2013    12.62  10.22  -2.40
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...