我需要从数据流中获取最新的更新消息。数据如下:
test_data =
[{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'},
{u'category': u'3',
u'entity': u'entityD',
u'length': u'6',
u'timestamp': u'1562422645'}]
建议采用以下方法here
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)}
返回此值(它完全按预期工作):
{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'},
u'entityD': {u'category': u'3',
u'entity': u'entityD',
u'length': u'6',
u'timestamp': u'1562422645'}}
问题是我有7k个唯一的“实体”,并且“ test_data”中有多达700万个列表项。上面的解决方案需要很长时间,我想知道是否有更快的方法。
答案 0 :(得分:1)
您应该能够通过一个单一的比较就可以做到这一点。在循环过程中,只需跟踪每个类别到目前为止所能看到的最大值即可:
from collections import defaultdict
def getMax(test_data):
d = defaultdict(lambda: {'timestamp':0})
for item in test_data:
if int(item['timestamp']) > int(d[item['entity']]['timestamp']):
d[item['entity']] = item
return d
返回值将是一个字典,键为entity
,每个字典的最大值。在循环中排序或构建数组的速度应该明显更快。仍然有700万需要一段时间。
答案 1 :(得分:1)
看起来像纯Python解决方案可能无法满足您的需求,我建议您使用pandas
,它的性能可能会好得多。
你可以试试吗?
import pandas as pd
test_data = [{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'},
{u'category': u'3',
u'entity': u'entityD',
u'length': u'6',
u'timestamp': u'1562422645'}]
df = pd.DataFrame(test_data)
df["timestamp"] = df["timestamp"].astype(int)
print(df.loc[df.groupby("entity")["timestamp"].idxmax()].to_dict(orient='records'))
答案 2 :(得分:0)
您可以使用max
代替sorted
,因为您只需要最大的条目,而无需对其余项进行排序:
test_alexander = {entity: max([d for d in test_data if d.get('entity') == entity], key=lambda x: x['timestamp'])
for entity in set(d.get('entity') for d in test_data)}
((最大值将为O(n),排序将为O(n * logn))
答案 3 :(得分:0)
我将从按实体划分开始,然后使用max来获取每个实体的最新记录。这将具有线性复杂度。您具有的代码会进行过滤,然后对接近三次的每个实体进行记录排序。
在Python中,它看起来像:
partitions = dict()
for record in test_data:
partitions.setdefault(record['entity'], []).append(record)
# replace this with defaultdict for 2x performance
for key in partitions:
partitions[key] = max(partitions[key], key=lambda x: int(x['timestamp']))
结果在partitions
中。并且形状为{entity:[{}]}
。
可以通过用max调用代替累积来减少内存使用量,但这实际上可能会更慢。
答案 4 :(得分:0)
这应该可以解决问题。它会一次扫描测试数据并记录每个实体的最新消息:
from collections import defaultdict
latest_message = defaultdict(lambda: dict('timestamp'=0)
for data in test_data:
latest = latest_message[data[entity]]
if data['timestamp'] > latest['timestamp']:
latest_message[data[entity]].update(data)