我正在尝试从数据流中获取到实体的最新更新消息。数据以字典列表的形式出现,其中每个字典都是对实体的更新消息。我只需要实体的最新更新。我的输入是字典列表,而输出则必须是字典字典
注意:仅更新长度,类别保持不变。我知道哪个是最新的更新,因为对于该实体,它将具有最新的时间戳记
数据如下:
[{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中执行此操作,似乎无法在python中通过SQL来解决问题,但是我的上游数据SQL不支持row_number()
在我尝试了吉莱斯皮和亚历山大的方法后更新了这个问题。 Gillespie的方法似乎行不通,Alexander的方法行得通,但在处理大量数据时会变得非常慢-有任何更快的选择吗?
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'}}
答案 0 :(得分:0)
假设您的数据已分配给名为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'}}
一种更快的方法将涉及使用pandas。
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'}]
答案 1 :(得分:0)
如果您有类似的问题,请最好在新问题中对我的后续问题进行框架设计: Is there a faster alternative to this approach to get last update message from list of dict?
答案 2 :(得分:0)
尝试这样的事情:
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'}