我注意到 pandas Series.map() 对于 dict 映射非常快
准备如下数据:
a=np.random.randint(0,1000,10**5)
s=pd.Series(a)
d=dict(zip(np.arange(1000),np.random.random(1000)))
时间
%timeit -n10 s.map(d)
%timeit -n10 np.vectorize(d.get)(a)
给予
1.42 ms ± 168 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
20.6 ms ± 386 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
第二种方法是我在 stackoverflow 上发现的进行 numpy dict 映射的典型推荐。
numpy还有一个典型的解决方案如下
%%timeit -n10
b = np.copy(a)
for k, v in d.items():
b[a==k] = v
给出
43.9 ms ± 2.8 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
它甚至更慢,更糟糕的是,它给出了错误的结果。因为 b
是 int 类型,赋值 b[a==k] = v
将返回 b 将全为零!
所以我想知道 pandas Series.map() 的内部实现是什么?它在 numpy 中实现了吗?与具有相同性能的 Series.map() 等效的 numpy 是什么?我试图深入研究 Series.map() 的源代码,但无法理解它。
最佳答案
Series.map
将调用 _map_values()
这是 pandas/core/base.py 的一部分
你正在使用字典,所以你通过第一个 if is_dict_like(mapper):
子句来获取 mapper
,然后在第 1161-1162 行你得到此基本情况的映射函数(默认为 na_action=None
的非扩展类型)
else:
map_f = lib.map_infer
如果您随后转到 pandas/_libs/lib.pyx 中的那部分代码,您将看到 map_infer
is implemented in cython
.
正如他们在评论中指出的那样,这对于特定的输入来说非常快:
# we can fastpath dict/Series to an efficient map
# as we know that we are not going to have to yield
# python types
关于python - pandas Series.map() 的内部实现是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60023136/