Itertools将性能问题与大列表相结合



我在tickers_list中有一个tickers列表,我需要对唯一元素进行组合。

这是我的代码:

corr_list = []
i = 0
for ticker in tickers_list:
    tmp_list = tickers_list[i+1:]
    for tl_ticker in tmp_list:
        corr_list.append({'ticker1':ticker, 'ticker2':tl_ticker})
    i = i+1
len(corr_list)

以下是使用itermitems的代码:

from itertools import combinations
result = combinations(tickers_list, 2)
new_list = [{'ticker1':comb[0], 'ticker2':comb[1]} for comb in combinations(tickers_list, 2)]
len(new_list)

产生完全相同的结果。当然,itertitems代码要优雅得多,并且两者都可以完美地处理10、100和1000个项目。所需时间几乎相同(我计时)。然而,在4000个项目的情况下,我的代码在我的机器上运行大约需要12秒,而itertions会使我的计算机崩溃。发送的结果只有大约20m行,所以我是做错了什么,还是这是itermItems的问题?

from itertools import combinations, product
# 20 * 20 * 20 == 8000 items
tickers_list = ["".join(chars) for chars in product("ABCDEFGHIJKLMNOPQRST", repeat=3)]
# 8000 * 7999 / 2 == 31996000 (just under 32 million) items
unique_pairs = [{"ticker1":t1, "ticker2":t2} for t1,t2 in combinations(tickers_list, 2)]

在我的机器(Win7Pro x64,Python 3.4)上运行良好,最高可达len(tickers_list) == 8000(需要38秒,消耗近76 GiB的RAM!)。

您运行的是32位还是64位Python?你真的需要存储所有的组合吗?或者你可以边使用边丢弃它们吗?


编辑:我计算错了大小;它实际上大约是9.5吉布。自己试试:

from sys import getsizeof as size
size(unique_pairs) + len(unique_pairs) * size(unique_pairs[0])

它给出

9479596592  # total size of structure in bytes == 9.5 GiB 

无论如何,这不是使用itertools的结果;它是dict结果列表的内存占用,无论你如何生成它,它都是一样的。你的计算机可能无论如何都可以使用虚拟RAM(交换到磁盘)来处理它,尽管它要慢得多。

如果你这样做只是为了把它放入数据库,我建议让数据库来做这项工作:制作一个包含tickers_list项目的表,然后选择一个交叉连接来生成最终的表,比如

SELECT a.ticker, b.ticker
FROM
    tickers as a,
    tickers as b
WHERE
    a.ticker < b.ticker

最新更新