massef
@massef

Как просумировать значение в дубликатах строк с поиском по дате?

Есть таблица с данными по автомобилям, в ней есть колонка "view" (кол-во просмотров за сутки) и колонка с датой.
Нужно сформировать новый фрейм просумировав просмотры конкретной машины за например неделю или месяц.

Сделал простой пример тут в песочнице https://code.sololearn.com/cOAXyhEmN1f7
Дубликаты получилось найти, но как найти конкретную машину за разные даты?
К примеру имеем:
mark type  view        date
0   bmw   v1     2  01-01-2020
1   bmw   v1     8  02-01-2020
2   bmw   v2     5  04-02-2020
3  audi   v1     3  09-02-2020
4  audi   v1     8  21-03-2020
5   kia   v1    13  24-03-2020

-------- Дубликаты
   mark type  view        date
1   bmw   v1     8  02-01-2020
4  audi   v1     8  21-03-2020


Нужно получить:
mark type  view
0   bmw   v1    10 
1   bmw   v2    5 
2  audi   v1    11 
3   kia   v1    13
  • Вопрос задан
  • 92 просмотра
Решения вопроса 1
Hannnn
@Hannnn
Developer
Главная суть создать уникальный ключ и зрупировать данные.

get_key: создать ключ на основе базовых полей (string) и extra (eg: date);
combine_rows: что нужно сделать с дубликатами;
read_rows: pre-processor для входных данных.

Input (test.csv)

n,mark,type,view,date
0,bmw,v1,2,01-01-2020
1,bmw,v1,8,02-01-2020
2,bmw,v2,5,04-02-2020
3,audi,v1,3,09-02-2020
4,audi,v1,8,21-03-2020
5,kia,v1,13,24-03-2020


import csv

from datetime import datetime


def get_key(row, basic_path=('mark', 'type',), date_path=('year',)):
    key = '_'.join((str(row[bp]) for bp in basic_path))
    extra_key = '-'.join((str(getattr(row['date'], dp)) for dp in date_path))
    return f'{key}_{extra_key}'


def combine_rows(target_row, row):
    target_row['view'] += row['view']


def read_rows(path):
    with open(path, 'r') as handler:
        reader = csv.DictReader(handler)

        for row in reader:
            row['view'] = int(row['view'])
            row['date'] = datetime.strptime(row['date'], '%d-%m-%Y')

            yield row


def main():
    result = dict()

    basic_path = ('mark', 'type',)
    date_path = ('year',)

    for row in read_rows('test.csv'):
        key = get_key(row=row, basic_path=basic_path, date_path=date_path)

        if key not in result:
            result[key] = row
        else:
            combine_rows(target_row=result[key], row=row)

    for value in result.values():
        print(value)


if __name__ == '__main__':
    main()


Result 1 - групировать по марке и типу + год

Parameters
basic_path = ('mark', 'type',)
date_path = ('year',)

Output
{'n': '0', 'mark': 'bmw', 'type': 'v1', 'view': 10, 'date': datetime.datetime(2020, 1, 1, 0, 0)}
{'n': '2', 'mark': 'bmw', 'type': 'v2', 'view': 5, 'date': datetime.datetime(2020, 2, 4, 0, 0)}
{'n': '3', 'mark': 'audi', 'type': 'v1', 'view': 11, 'date': datetime.datetime(2020, 2, 9, 0, 0)}
{'n': '5', 'mark': 'kia', 'type': 'v1', 'view': 13, 'date': datetime.datetime(2020, 3, 24, 0, 0)}


Result 2 - групировать по марке и типу + месяц и года

Parameters
basic_path = ('mark', 'type',)
date_path = ('month', 'year',)

Output
{'n': '0', 'mark': 'bmw', 'type': 'v1', 'view': 10, 'date': datetime.datetime(2020, 1, 1, 0, 0)}
{'n': '2', 'mark': 'bmw', 'type': 'v2', 'view': 5, 'date': datetime.datetime(2020, 2, 4, 0, 0)}
{'n': '3', 'mark': 'audi', 'type': 'v1', 'view': 3, 'date': datetime.datetime(2020, 2, 9, 0, 0)}
{'n': '4', 'mark': 'audi', 'type': 'v1', 'view': 8, 'date': datetime.datetime(2020, 3, 21, 0, 0)}
{'n': '5', 'mark': 'kia', 'type': 'v1', 'view': 13, 'date': datetime.datetime(2020, 3, 24, 0, 0)}


PS: на идеально решение не претендую.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы