管理大点列表,最佳方法?

时间:2014-02-03 07:18:07

标签: python list python-2.7 data-structures dataset

我在我的代码中打了一个性能墙,并决定重写它,并需要一些关于如何解决这个问题的建议。 我有一个巨大的光流数据列表,包括带有框架,X和Y坐标的列表。 像这样:

[[[frame,x,y],[frame,x,y]],[[frame,x,y],[frame,x,y]]...]

我在此处上传了一个示例:http://pastebin.com/ANUr8bwc

我需要找到一种方法来管理这些数据,以便我可以快速查找并查看哪些列表包含某些帧。

到目前为止,我已遍历所有数据以查看哪些列表包含第34帧和第35帧,然后将它们编入新列表以供参考。

thisFrame = 34
nextFrame = thisFrame + 1
if any(e[0] == thisFrame for e in item) and any(e[0] == nextFrame for e in item): #Check if the item contains this frame and next
    DoStuff()

这样做几千次以获得10.000+点的列表很快就会变成瓶颈。所以我的想法是为每个帧制作一个dict,并以这种方式轻松地找到某个帧上可用的项目:

{frame, [list1,list2,list3]}

但我想我最好问这个时间。 是否有一个很好的goto方法用于存储和能够在大数据集中进行查找,以避免每次需要时都循环遍历所有这些?

2 个答案:

答案 0 :(得分:1)

Dictionaries是Python最优化的数据结构之一。将数据转换为字典需要一些时间,但之后,查找(例如thisFrame in item)在O(1)时间内完成,这比列表快得多。

你最好的选择是转换成字典,使用这样的代码:

N.B。看起来您的列表嵌套了两次,如果不是这样,您将不得不稍微修改一下迭代。

item_dict = {}
for big_lst in item:
    for lst in big_lst:
        try:
            item_dict[lst[0]] += [lst[1:],] # Append to existing value
        except KeyError:
            item_dict[lst[0]] = [lst[1:],] # Initialize value

编辑02/05:尝试/除了更快

item_dict将如下所示,合并重复的帧,以便单个帧查找将返回[x,y]对的列表。

item_dict = {
    1: [list1, list2, list3]
    2: [list1, list2]
    3: [list1]
    4: [list1, list2, list3]
}

从那时起,查找将非常快:

thisFrame = 34
nextFrame = thisFrame + 1
if thisFrame in item_dict and nextFrame in item_dict:
    foo = item_dict[thisFrame] # e.g. [list1, list2]
    bar = item_dict[nextFrame] # e.g. [list1, list2, list3]
    DoStuff()

如果您需要跟踪单个[x,y]对所属的父列表,您可以在item中添加每个列表的一个附加元素,用于存储父列表的索引:

item_dict = {}
for list_index, big_lst in enumerate(item):
    for lst in big_lst:
        if lst[0] in item_dict:
            item_dict[lst[0]] += [lst[1:]+[list_index],] # Append
        else:
            item_dict[lst[0]] = [lst[1:]+[list_index],] # Initialize

然后,查找

parent_list = item_dict[thisFrame][2] # [x, y, list_index]

将返回可以访问的父列表:

item[parent_list]

答案 1 :(得分:1)

我想在这里做什么:

首先,我尝试通过创建一个名为frame的字典将所有x,y合并到唯一的框架中。 其次,我通过将值转换为键并将键转换为值来恢复字典。

如果有效,请告诉我:否则我会修改或删除它。

#!/usr/bin/python

import ast

dict_frame = dict()
def generate_datastructure():
    l = ''
    with open('2d_optical_tracking_data.txt', 'r') as fh:
        l = ast.literal_eval(fh.read())
    frame = dict()
    for ls in l:
        for elm in ls:
            key = elm[0]
            val_list = elm[1:]
            frame.setdefault(key, [])
            frame[key].extend(val_list)

    # convert all the value into set:
    for key, val in frame.iteritems():
        dict_frame[tuple(set(val))] = key

def lookup(key):
    print dict_frame

if __name__ == '__main__':
    tofind = '45.835999'
    generate_datastructure()
    for key, val in dict_frame.iteritems():
        if tofind in key:
            print val