use*_*964 3 python performance numpy pandas
我注意到 pandas Series.map() 对于字典映射来说非常快
\n\n准备数据如下:
\n\na=np.random.randint(0,1000,10**5)\ns=pd.Series(a)\nd=dict(zip(np.arange(1000),np.random.random(1000)))\nRun Code Online (Sandbox Code Playgroud)\n\n定时
\n\n%timeit -n10 s.map(d)\n%timeit -n10 np.vectorize(d.get)(a)\nRun Code Online (Sandbox Code Playgroud)\n\n给出
\n\n1.42 ms \xc2\xb1 168 \xc2\xb5s per loop (mean \xc2\xb1 std. dev. of 7 runs, 10 loops each)\n20.6 ms \xc2\xb1 386 \xc2\xb5s per loop (mean \xc2\xb1 std. dev. of 7 runs, 10 loops each)\nRun Code Online (Sandbox Code Playgroud)\n\n其中第二种方法是我在 stackoverflow 上找到的进行 numpy dict 映射的典型建议。
\n\nnumpy还有另一种典型的解决方案如下
\n\n%%timeit -n10 \nb = np.copy(a)\nfor k, v in d.items():\n b[a==k] = v\nRun Code Online (Sandbox Code Playgroud)\n\n这使
\n\n43.9 ms \xc2\xb1 2.8 ms per loop (mean \xc2\xb1 std. dev. of 7 runs, 10 loops each)\nRun Code Online (Sandbox Code Playgroud)\n\n它甚至更慢,更糟糕的是,它给出了错误的结果。因为b是int类型,赋值时b[a==k] = v会返回b全为零!
所以我想知道 pandas Series.map() 的内部实现是什么?它在numpy中实现吗?与具有相同性能的 Series.map() 等效的 numpy 是什么?我试图深入研究 Series.map() 的源代码,但无法理解它。
\nSeries.map将调用_map_values()pandas/core/base.py 的一部分
您使用的是字典,因此您可以通过第一个if is_dict_like(mapper):子句来获取mapper,然后在第 1161-1162 行中您将获得此基本情况的映射函数(默认为非扩展类型na_action=None)
else:
map_f = lib.map_infer
Run Code Online (Sandbox Code Playgroud)
If you then go to that part of the code, found in pandas/_libs/lib.pyx you'll see map_infer is implemented in cython.
As they note in the comments, this is only so fast for specific inputs:
# we can fastpath dict/Series to an efficient map
# as we know that we are not going to have to yield
# python types
Run Code Online (Sandbox Code Playgroud)