Получить последнее обновленное сообщение dict из списка dict - PullRequest
2 голосов
/ 06 июля 2019

Я пытаюсь получить последнее обновление сообщения для объекта из потока данных. Данные представляют собой список диктов, где каждый диктовок является сообщением об обновлении сущности. Мне нужно только последнее обновление объекта. Мой вклад приходит как список диктов, а вывод должен быть в диктантах

Примечания: обновляется только длина, категория остается статичной. Я знаю, какое из них является последним обновлением, потому что для этого объекта у него будет самая последняя отметка времени

Данные поступают так:

[{u'length': u'1',
  u'category': u'3',
  u'entity': u'entityA',
  u'timestamp': u'1562422690'},
 {u'length': u'1.1',
  u'category': u'3',
  u'entity': u'entityA',
  u'timestamp': u'1562422691'},
 {u'length': u'1.2',
  u'category': u'3',
  u'entity': u'entityA',
  u'timestamp': u'1562422692'},
 {u'length': u'0.9',
  u'category': u'3',
  u'entity': u'entityB',
  u'timestamp': u'1562422689'},
 {u'length': u'0.9',
  u'category': u'3',
  u'entity': u'entityB',
  u'timestamp': u'1562422690'}]

Мне нужно манипулировать этим, чтобы получить только:

{u'entityA':{u'length': u'1.2', 
             u'category': u'3', 
             u'entity': u'entityA', 
             u'timestamp': u'1562422692'},
 u'entityB':{u'length': u'0.9', 
             u'category': u'3', 
             u'entity': u'entityB', 
             u'timestamp': u'1562422690'}}

Я новичок в python - я знал, что могу добиться этого в SQL с помощью:

select * from
(select
   length, 
   category, 
   entity, 
   timestamp, 
   row_number () over (partition by entity order by timestamp desc) as rnumb
from data
)foo
where rnumb = 1

но я делаю это в python, и кажется, что это обходной путь для обхода SQL в python, к сожалению, мой SQL-код для исходных данных не поддерживает row_number ()

Обновление этого вопроса после того, как я попробовал подходы Гиллеспи и Александра. Подход Гиллеспи, похоже, не работает, Александр работает, но становится очень медленным при работе с большим количеством данных - есть ли более быстрая альтернатива?

test_data = [
{u'length': u'0',
  u'category': u'3',
  u'entity': u'entityA',
  u'timestamp': u'1562422690'},
{u'length': u'1',
  u'category': u'3',
  u'entity': u'entityA',
  u'timestamp': u'1562422680'},
{u'length': u'2',
  u'category': u'3',
  u'entity': u'entityB',
  u'timestamp': u'1562422691'},
{u'length': u'3',
  u'category': u'3',
  u'entity': u'entityB',
  u'timestamp': u'1562422688'},
{u'length': u'4',
  u'category': u'3',
  u'entity': u'entityC',
  u'timestamp': u'1562422630'},
{u'length': u'5',
  u'category': u'3',
  u'entity': u'entityC',
  u'timestamp': u'1562422645'}
]
>>> test_gillespie = max(test_data, lambda x: x["timestamp"])
test_gillespie
[{u'category': u'3',
  u'entity': u'entityA',
  u'length': u'0',
  u'timestamp': u'1562422690'},
 {u'category': u'3',
  u'entity': u'entityA',
  u'length': u'1',
  u'timestamp': u'1562422680'},
 {u'category': u'3',
  u'entity': u'entityB',
  u'length': u'2',
  u'timestamp': u'1562422691'},
 {u'category': u'3',
  u'entity': u'entityB',
  u'length': u'3',
  u'timestamp': u'1562422688'},
 {u'category': u'3',
  u'entity': u'entityC',
  u'length': u'4',
  u'timestamp': u'1562422630'},
 {u'category': u'3',
  u'entity': u'entityC',
  u'length': u'5',
  u'timestamp': u'1562422645'}]
>>>test_alexander = {entity: sorted([d for d in test_data if d.get('entity') == entity], key=lambda x: x['timestamp'])[-1]
     for entity in set(d.get('entity') for d in test_data)}
test_alexander
{u'entityA': {u'category': u'3',
  u'entity': u'entityA',
  u'length': u'0',
  u'timestamp': u'1562422690'},
 u'entityB': {u'category': u'3',
  u'entity': u'entityB',
  u'length': u'2',
  u'timestamp': u'1562422691'},
 u'entityC': {u'category': u'3',
  u'entity': u'entityC',
  u'length': u'5',
  u'timestamp': u'1562422645'}}

Ответы [ 3 ]

0 голосов
/ 07 июля 2019

Я бы лучше сформулировал свой дополнительный вопрос о производительности в новом вопросе, если у вас есть похожая проблема, проверьте его: Есть ли более быстрая альтернатива этому подходу для получения последнего сообщения об обновлении из списка dict?

0 голосов
/ 07 июля 2019

Попробуйте что-то вроде этого:

test_data = [
{u'length': u'0',
  u'category': u'3',
  u'entity': u'entityA',
  u'timestamp': u'1562422690'},
{u'length': u'1',
  u'category': u'3',
  u'entity': u'entityA',
  u'timestamp': u'1562422680'},
{u'length': u'2',
  u'category': u'3',
  u'entity': u'entityB',
  u'timestamp': u'1562422691'},
{u'length': u'3',
  u'category': u'3',
  u'entity': u'entityB',
  u'timestamp': u'1562422688'},
{u'length': u'4',
  u'category': u'3',
  u'entity': u'entityC',
  u'timestamp': u'1562422630'},
{u'length': u'5',
  u'category': u'3',
  u'entity': u'entityC',
  u'timestamp': u'1562422645'}
]

test_gillespie = max(test_data, key=lambda x: int(x["timestamp"]))

print(test_gillespie)

Вывод:

{'length': '2', 'category': '3', 'entity': 'entityB', 'timestamp': '1562422691'}

См .: https://repl.it/repls/StimulatingLightcoralBotany

0 голосов
/ 06 июля 2019

Предполагая, что ваши данные присвоены переменной с именем data, вы можете использовать словарное понимание вместе с sorted. Для каждой сущности (set(d.get('entity') for d in data) создает набор всех уникальных сущностей) сортируйте ее данные на основе отметки времени, а затем возьмите последний элемент (т.е. самый последний) с помощью выбора индекса [-1].

>>> {entity: sorted([d for d in data if d.get('entity') == entity], key=lambda x: x['timestamp'])[-1]
     for entity in set(d.get('entity') for d in data)}
{'entityA': {'length': '1.2',
  'category': '3',
  'entity': 'entityA',
  'timestamp': '1562422692'},
 'entityB': {'length': '0.9',
  'category': '3',
  'entity': 'entityB',
  'timestamp': '1562422690'}}

Более быстрый метод предполагает использование панд .

import pandas as pd

df = pd.DataFrame(data).sort_values('timestamp')
result = df.groupby('entity', as_index=False).last()
>>> result
    entity category length   timestamp
0  entityA        3    1.2  1562422692
1  entityB        3    0.9  1562422690

>>> result.to_dict('r')
[{'entity': 'entityA',
  'category': '3',
  'length': '1.2',
  'timestamp': '1562422692'},
 {'entity': 'entityB',
  'category': '3',
  'length': '0.9',
  'timestamp': '1562422690'}]

1013 *

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...