группировать список словарей по ключам и создавать месячные временные рамки для каждого ключа, считая каждый месяц - PullRequest
1 голос
/ 11 марта 2020

Представьте, что у вас есть список словарей:

lst = [{'id': 1, 'upload_date': '05-01-2019'}, {'id': 1, 'upload_date': '06-01-2019'}, {'id': 1, 'upload_date': '08-02-2020'}, {'id': 2, 'upload_date': '08-04-2019'}, {'id': 3, 'upload_date': '06-01-2019'}]

Вывод списка словарей:

[{'id': 1, 'upload_date': '05-01-2019'},
 {'id': 3, 'upload_date': '06-02-2019'},
 {'id': 1, 'upload_date': '06-01-2019'},
 {'id': 1, 'upload_date': '08-02-2020'},
 {'id': 2, 'upload_date': '08-04-2019'}]

Я хочу сгруппировать список словарей по идентификатору, а затем для каждого идентификатора создать график времени с 1 января 2019 года по март 2020 года. Затем для каждого месяца в пределах этого графика времени я хочу подсчитать, сколько раз произошел месяц.

До сих пор мне удавалось создать месячный график времени между этими двумя датами с помощью:

timeline = pd.date_range('01-01-2019','03-01-2020', freq='MS').strftime("%m-%Y").tolist()

Выходная временная шкала:

['01-2019', '02-2019', '03-2019', '04-2019', '05-2019', '06-2019', '07-2019', '08-2019', '09-2019', '10-2019', '11-2019', '12-2019', '01-2020', '02-2020', '03-2020']

Итак, желаемый вывод должен быть примерно таким:

1 : ['01-2019': 2, '02-2019': '0', '03-2019': 0, '04-2019': 0, ......... ,'02-2020': 1]
2 : ['01-2019': 0, '02-2019': '0', '03-2019': 0, '04-2019': 1, ......... ,'02-2020': 0]
3 : ['01-2019': 0, '02-2019': '1', '03-2019': 0, '04-2019': 0, ......... ,'02-2020': 0]

1 Ответ

0 голосов
/ 11 марта 2020

Обновление: Я понял, что вы ищете счетчики MM-YYYY, а не MM-DD-YYYY, приведенный ниже код должен работать как нужно. Теперь используйте datetime для разбора даты и переместили понимание набора в большое гнездо.


Это не очень красиво, но оно выполняет свою работу. Я гарантирую, что есть еще Pythoni c способ добиться этого.

from datetime import datetime

lst = [
    {'id': 1, 'upload_date': '05-01-2019'},
    {'id': 3, 'upload_date': '06-02-2019'},
    {'id': 1, 'upload_date': '06-01-2019'},
    {'id': 1, 'upload_date': '08-02-2020'},
    {'id': 2, 'upload_date': '08-04-2019'},
]

# Remove day from lst dates
lst = [
    {
        "id": i["id"],
        "upload_date": f'{datetime.strptime(i["upload_date"], "%m-%d-%Y"):%m-%Y}',
    }
    for i in lst
]

# Four layer comprehension
# - id_dates = {i: {dictcomp} for i in {setcomp}}
#   - {dictcomp} = {date: [listcomp].count(date) if same ID}
#     - [listcomp] = [date for date in list if same ID]
#   - {setcomp} = {id for id in list}
id_dates = {
    i: {
        dct["upload_date"]: [d["upload_date"] for d in lst if d["id"] == i].count(
            dct["upload_date"]
        )
        for dct in lst
        if dct["id"] == i
    }
    for i in {i["id"] for i in lst}
}

for _id, counts in id_dates.items():
    print(f"{_id}: {counts}")

Вывод

1: {'05-2019': 1, '06-2019': 1, '08-2020': 1}
2: {'08-2019': 1}
3: {'06-2019': 1}

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

...