考虑一下这个熊猫系列词典。所有系列的索引都是整数,并且有一些潜在的重叠,但肯定不重合。当我有大量索引,大量非重叠以及许多要连接的项时,我发现pd.concat
在axis=1
中组合时似乎很慢。它促使我离开axis=0
,然后离开unstack()
。我最终得到了同样的结果。但是拆散更快。
有没有人知道为什么会出现这种情况?
我认为连接系列应该很快,但我猜想卸载过程与pd.concat(axis=1)
几乎完全相同。
dict_of_series = {
's%s' % i: pd.Series(
1, np.unique(np.random.randint(1000, 10000, size=1000))
) for i in range(100)
}
%%timeit
pd.concat(dict_of_series, axis=0).unstack(0)
10个循环,最佳3:29.6毫秒/循环
%%timeit
pd.concat(dict_of_series, axis=1)
10个循环,最佳3:每循环43.1 ms
答案 0 :(得分:3)
快速分析显示pd.concat(dict_of_series, axis=1)
消耗了pd.Index.union
中的大量时间。它在内部函数_union_indexes
内逐个调用每个索引 - 与我下面的函数union
类似。
另一方面,pd.concat(dict_of_series, axis=0).unstack(0)
使用了一些聪明的优化,我没有尝试分析。无论如何,那里没有_union_indexes
甚至pd.Index.union
的电话。
可以' _union_indexes'是罪魁祸首?很可能。我只拿了索引:
idxs = [d.index for d in dict_of_series.values()]
并比较了以下两个函数:
def union(idxs):
ans = pd.Index([])
for idx in idxs:
ans = ans.union(idx)
return ans
def union_multi(idxs):
arr0 = np.concatenate(idxs)
arr1 = np.zeros(arr0.size)
ans = pd.MultiIndex.from_arrays([arr0, arr1])
return ans.levels[0]
union
相当于_union_indexes
,而union_multi
有一些多索引开销,但无法调用pd.Index.union
。
我粗略的时间:
>>> %timeit -n1 -r1 pd.concat(dict_of_series, axis=1)
1 loop, best of 1: 82.9 ms per loop
>>> %timeit -n1 -r1 pd.concat(dict_of_series, axis=0).unstack(0)
1 loop, best of 1: 57.9 ms per loop
>>> %timeit -n1 -r1 union(idxs)
1 loop, best of 1: 32.8 ms per loop
>>> %timeit -n1 -r1 union_multi(idxs)
1 loop, best of 1: 12.5 ms per loop
简单的pd.Index(np.unique(np.concatenate(idxs)))
稍快一点,但对混合类型不起作用。
(顺便说一下,pd.concat
仅在所有索引都是唯一的情况下才有效。)