Выполните итерацию по кортежу, вложенному в список, и выберите топ 1 для каждой группы кортежей на основе даты - PullRequest
0 голосов
/ 24 февраля 2020

относительно новый для Python, не новый для программирования. Для меня существуют системные ограничения, когда я не могу выполнить эту операцию с помощью SQL - мне нужно сделать все это с помощью Python 3.x.

Мне нужно получить подмножество данных образца ниже сгруппированы по FIELD1, FIELD2, FIELD3 и отсортированы по FIELD5 (дата) AS C.

Пример данных:

    [['FIELD1', 'FIELD2', 'FIELD3', 'FIELD4', 'FIELD5'], 
    (9220123, '18002744100', 'BICYCLE', 'RED', datetime.datetime(2019, 2, 10, 23, 17, 47, 300172)), 
    (9220123, '18002744100', 'BICYCLE', 'RED', datetime.datetime(2019, 2, 11, 0, 14, 49, 342347)), 
    (9220123, '18002744100', 'BICYCLE', 'RED', datetime.datetime(2019, 2, 10, 23, 40, 49, 756362)), 
    (9220123, '18002744100', 'MOTORCYCLE', 'GREEN', datetime.datetime(2019, 2, 11, 0, 14, 49, 342347)), 
    (9220123, '18002744100', 'MOTORCYCLE', 'GREEN', datetime.datetime(2019, 2, 10, 23, 40, 49, 756362)), 
    (9220123, '18002744100', 'MOTORCYCLE', 'GREEN', datetime.datetime(2019, 2, 10, 23, 17, 47, 300172)), 
    (9220123, '18002744100', 'UNICYCLE', 'PLAID', datetime.datetime(2019, 2, 10, 23, 40, 49, 756362)), 
    (9220123, '18002744100', 'UNICYCLE', 'PINK', datetime.datetime(2019, 2, 10, 23, 17, 47, 300172)), 
    (9220123, '18002744100', 'UNICYCLE', 'BLUE', datetime.datetime(2019, 2, 11, 0, 14, 49, 342347)), 
    (9220123, '18002744100', 'UNICYCLE', 'PURPLE', datetime.datetime(2019, 2, 11, 2, 23, 16, 395861)), ...

Набор результатов:

    (9220123, '18002744100', 'BICYCLE', 'RED', datetime.datetime(2019, 2, 11, 0, 14, 49, 342347)), 
    (9220123, '18002744100', 'MOTORCYCLE', 'GREEN', datetime.datetime(2019, 2, 11, 0, 14, 49, 342347)), 
    (9220123, '18002744100', 'UNICYCLE', 'PURPLE', datetime.datetime(2019, 2, 11, 2, 23, 16, 395861)),... 

Спасибо!

1 Ответ

0 голосов
/ 24 февраля 2020

Предполагая, что входные данные уже отсортированы по группам, мы можем использовать groupby, чтобы изолировать эти группы, а затем запустить max над ними, чтобы получить запись с наибольшей датой:

import datetime
from operator import itemgetter
from itertools import groupby

l = [(9220123, '18002744100', 'BICYCLE', 'RED', datetime.datetime(2019, 2, 10, 23, 17, 47, 300172)), 
    (9220123, '18002744100', 'BICYCLE', 'RED', datetime.datetime(2019, 2, 11, 0, 14, 49, 342347)), 
    (9220123, '18002744100', 'BICYCLE', 'RED', datetime.datetime(2019, 2, 10, 23, 40, 49, 756362)), 
    (9220123, '18002744100', 'MOTORCYCLE', 'GREEN', datetime.datetime(2019, 2, 11, 0, 14, 49, 342347)), 
    (9220123, '18002744100', 'MOTORCYCLE', 'GREEN', datetime.datetime(2019, 2, 10, 23, 40, 49, 756362)), 
    (9220123, '18002744100', 'MOTORCYCLE', 'GREEN', datetime.datetime(2019, 2, 10, 23, 17, 47, 300172)), 
    (9220123, '18002744100', 'UNICYCLE', 'PLAID', datetime.datetime(2019, 2, 10, 23, 40, 49, 756362)), 
    (9220123, '18002744100', 'UNICYCLE', 'PINK', datetime.datetime(2019, 2, 10, 23, 17, 47, 300172)), 
    (9220123, '18002744100', 'UNICYCLE', 'BLUE', datetime.datetime(2019, 2, 11, 0, 14, 49, 342347)), 
    (9220123, '18002744100', 'UNICYCLE', 'PURPLE', datetime.datetime(2019, 2, 11, 2, 23, 16, 395861))]

groups = map(itemgetter(1), groupby(l, key=itemgetter(0, 1, 2)))
maxes = [max(g, key=itemgetter(4)) for g in groups]
print(maxes)

print

[(9220123, '18002744100', 'BICYCLE', 'RED', datetime.datetime(2019, 2, 11, 0, 14, 49, 342347)), 
 (9220123, '18002744100', 'MOTORCYCLE', 'GREEN', datetime.datetime(2019, 2, 11, 0, 14, 49, 342347)), 
 (9220123, '18002744100', 'UNICYCLE', 'PURPLE', datetime.datetime(2019, 2, 11, 2, 23, 16, 395861))]
...