from collections import defaultdict
dct = defaultdict(list)
for n in range(len(res)):
for i in indices_ordered:
dct[i].append(res[n][i])
注意res是一个长度为5000的pandas Series列表,indices_ordered是一个长度为20000的字符串列表。在我的Mac(2.3 GHz Intel Core i5 和 16 GB 2133 MHz LPDDR3) 运行此代码。我是 Python 的新手,但我觉得更聪明的编码(可能更少的循环)会有很大帮助。
编辑:
这是一个示例,说明如何创建数据(res 和 indices_ordered)以便能够在代码段之上运行(稍微更改以访问唯一字段而不是按字段名,因为我找不到如何使用字段名构建内联系列)
import random, string, pandas
index_sz = 20000
res_sz = 5000
indices_ordered = [''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(10)) for i in range(index_sz)]
res = [pandas.Series([random.randint(0,10) for i in range(index_sz)], index = random.sample(indices_ordered, index_sz)) for i in range(res_sz)]
请您参考如下方法:
这里的问题是您要为每个值迭代 indices_ordered。只需删除 indices_ordered。以数量级方式剥离它以测试时间:
import random
import string
import numpy as np
import pandas as pd
from collections import defaultdict
index_sz = 200
res_sz = 50
indices_ordered = [''.join(random.choice(string.ascii_uppercase + string.digits)
for _ in range(10)) for i in range(index_sz)]
res = [pd.Series([random.randint(0,10) for i in range(index_sz)],
index = random.sample(indices_ordered, index_sz))
for i in range(res_sz)]
def your_way(res, indices_ordered):
dct = defaultdict(list)
for n in range(len(res)):
for i in indices_ordered:
dct[i].append(res[n][i])
def my_way(res):
dct = defaultdict(list)
for item in res:
for string_item, value in item.iteritems():
dct[string_item].append(value)
给予:
%timeit your_way(res, indices_ordered)
160 ms ± 5.45 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit my_way(res)
6.79 ms ± 47.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
这降低了整个方法的时间复杂度,因为您不必每次都遍历 indicies_ordered 并分配值,因此随着数据量的增长,差异会变得更加明显。
只增加一个数量级:
index_sz = 2000
res_sz = 500
给予:
%timeit your_way(res, indices_ordered)
17.8 s ± 999 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit my_way(res)
543 ms ± 9.07 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
