假设我有一个熊猫系列,希望用作多图(每个索引键有多个值):
# intval -> data1
a = pd.Series(data=-np.arange(100000),
index=np.random.randint(0, 50000, 100000))
我想(尽快)选择a
中的所有值
其中a
的索引与另一个索引b
匹配。 (例如内部联接。或者是合并,但是对于系列)。
a
的索引中可能有重复项。b
可能没有重复,也不一定是a
索引的子集。为了给熊猫最大的机会,我们假设b
也可以作为已排序的索引对象提供: b = pd.Index(np.unique(np.random.randint(30000, 100000, 100000))).sortvalues()
所以,我们会有类似的东西:
target
a b result
3 0 3 3 0
3 1 7 8 3
4 2 8 ...
8 3 ...
9 4
...
我也只想获取结果的值(不需要索引[3,8,...]
)。
如果a
没有重复,我们将简单地做:
a.reindex(b) # Cannot reindex a duplicate axis
因为&
维护着a
的重复项,所以我们不能这样做:
d = a[a.index & b.index]
d = a.loc[a.index & b.index] # same
d = a.get(a.index & b.index) # same
print d.shape
所以我认为我们需要做类似的事情:
common = (a.index & b.index).unique()
a.loc[common]
...这很麻烦,但速度却令人惊讶。它不是建立缓慢的选择项列表:
%timeit (a.index & b).unique()
# 100 loops, best of 3: 3.39 ms per loop
%timeit (a.index & b).unique().sort_values()
# 100 loops, best of 3: 4.19 ms per loop
...所以看起来它确实在检索缓慢的值:
common = ((a.index & b).unique()).sort_values()
%timeit a.loc[common]
#10 loops, best of 3: 43.3 ms per loop
%timeit a.get(common)
#10 loops, best of 3: 42.1 ms per loop
...大约每秒20次操作。不完全是zippy!为什么这么慢?
肯定有一种快速的方法可以从pandas数据框中查找值集吗?我不想获取索引对象-实际上,我要提供的只是对已排序索引的合并,或者是(较慢的)哈希int查找。无论哪种方式,这都应该是极其的快速操作-而不是我的3Ghz机器上每秒20的操作。
也:
分析a.loc[common]
给出:
ncalls tottime percall cumtime percall filename:lineno(function)
# All the time spent here.
40 1.01 0.02525 1.018 0.02546 ~:0(<method 'get_indexer_non_unique' indexing.py:1443(_has_valid_type)
...
# seems to be called a lot.
1500 0.000582 3.88e-07 0.000832 5.547e-07 ~:0(<isinstance>)
PS。我之前发布了一个类似的问题,关于为什么Series.map这么慢 Why is pandas.series.map so shockingly slow?。原因是在引擎盖下偷懒。这似乎没有发生。
更新:
对于大小类似的a和常见的a是唯一的:
% timeit a.loc[common]
1000 loops, best of 3: 760 µs per loop
... @jpp指出。多索引很可能会造成责任。
答案 0 :(得分:1)
保证重复索引会减慢您的数据框索引操作。您可以修改输入内容以向自己证明这一点:
a = pd.Series(data=-np.arange(100000), index=np.random.randint(0, 50000, 100000))
%timeit a.loc[common] # 34.1 ms
a = pd.Series(data=-np.arange(100000), index=np.arange(100000))
%timeit a.loc[common] # 6.86 ms
当索引唯一时,熊猫使用哈希表将键映射到值O(1)。 当索引不唯一且已排序时,熊猫使用二进制搜索O(logN), 当指数是随机的有序的大熊猫需要检查的所有键 索引O(N)。