Title: Pandas、Numpy性能优化秘籍(全) · Issue #48 · aialgorithm/Blog · GitHub
Open Graph Title: Pandas、Numpy性能优化秘籍(全) · Issue #48 · aialgorithm/Blog
X Title: Pandas、Numpy性能优化秘籍(全) · Issue #48 · aialgorithm/Blog
Description: pandas、numpy是Python数据科学中非常常用的库,numpy是Python的数值计算扩展,专门用来处理矩阵,它的运算效率比列表更高效。pandas是基于numpy的数据处理工具,能更方便的操作大型表格类型的数据集。 但是,随着数据量的剧增,有时numpy和pandas的速度就成瓶颈。如下我们会介绍一些优化秘籍:里面包含 代码上面的优化,以及可以无脑使用的性能优化扩展包。 1、NumExpr NumExpr 是一个对NumPy计算式进行的性能优化。NumExp...
Open Graph Description: pandas、numpy是Python数据科学中非常常用的库,numpy是Python的数值计算扩展,专门用来处理矩阵,它的运算效率比列表更高效。pandas是基于numpy的数据处理工具,能更方便的操作大型表格类型的数据集。 但是,随着数据量的剧增,有时numpy和pandas的速度就成瓶颈。如下我们会介绍一些优化秘籍:里面包含 代码上面的优化,以及可以无脑使用的性能优化扩展包。 1、Nu...
X Description: pandas、numpy是Python数据科学中非常常用的库,numpy是Python的数值计算扩展,专门用来处理矩阵,它的运算效率比列表更高效。pandas是基于numpy的数据处理工具,能更方便的操作大型表格类型的数据集。 但是,随着数据量的剧增,有时numpy和pandas的速度就成瓶颈。如下我们会介绍一些优化秘籍:里面包含 代码上面的优化,以及可以无脑使用的性能优化扩展包。 1、Nu...
Opengraph URL: https://github.com/aialgorithm/Blog/issues/48
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Pandas、Numpy性能优化秘籍(全)","articleBody":"pandas、numpy是Python数据科学中非常常用的库,numpy是Python的数值计算扩展,专门用来处理矩阵,它的运算效率比列表更高效。pandas是基于numpy的数据处理工具,能更方便的操作大型表格类型的数据集。\r\n\r\n但是,随着数据量的剧增,有时numpy和pandas的速度就成瓶颈。如下我们会介绍一些优化秘籍:里面包含 代码上面的优化,以及可以无脑使用的性能优化扩展包。\r\n\r\n### 1、NumExpr\r\nNumExpr 是一个对NumPy计算式进行的性能优化。NumExpr的使用及其简单,只需要将原来的numpy语句使用双引号框起来,并使用numexpr中的evaluate方法调用即可。经验上看,数据有上万条+ 使用NumExpr才比较优效果,对于简单运算使用NumExpr可能会更慢。如下较复杂计算,速度差不多快了5倍。\r\n```\r\nimport numexpr as ne\r\n\r\nimport numpy as np\r\n\r\na = np.linspace(0,1000,1000) \r\n\r\nprint('# numpy十次幂计算')\r\n%timeit a**10\r\n\r\nprint('# numexpr十次幂计算')\r\n%timeit ne.evaluate('a**10')\r\n```\r\n\r\n\r\n### 2、Numba\r\nNumba 使用行业标准的[LLVM](https://llvm.org/)编译器库在运行时将 Python 函数转换为优化的机器代码。Python 中 Numba 编译的数值算法可以接近 C 或 FORTRAN 的速度。\r\n\r\n\r\n如果在你的数据处理过程涉及到了大量的数值计算,那么使用numba可以大大加快代码的运行效率(一般来说,Numba 引擎在处理大量数据点 如 1 百万+ 时表现出色)。numba使用起来也很简单,因为numba内置的函数本身是个装饰器,所以只要在自己定义好的函数前面加个@nb.方法就行,简单快捷!\r\n\r\n```\r\n# pip install numba\r\n\r\nimport numba as nb\r\n\r\n# 用numba加速的求和函数\r\n@nb.jit()\r\ndef nb_sum(a):\r\n Sum = 0\r\n for i in range(len(a)):\r\n Sum += a[i]\r\n return Sum\r\n\r\n# 没用numba加速的求和函数\r\ndef py_sum(a):\r\n Sum = 0\r\n for i in range(len(a)):\r\n Sum += a[i]\r\n return Sum\r\n\r\nimport numpy as np\r\na = np.linspace(0,1000,1000) # 创建一个长度为1000的数组\r\nprint('# python求和函数')\r\n%timeit sum(a) \r\nprint('# 没加速的for循环求和函数')\r\n%timeit py_sum(a)\r\nprint('# numba加速的for循环求和函数')\r\n%timeit nb_sum(a) \r\nprint('# numpy求和函数')\r\n%timeit np.sum(a) \r\n\r\n```\r\n\r\n当前示例可以看出,numba甚至比号称最接近C语言速度运行的numpy还要快5倍+,对于python求和速度快了几百倍。。\r\n\r\n此外,Numba还支持GPU加速、矢量化加速方法,可以进一步达到更高的性能。\r\n\r\n```\r\nfrom numba import cuda\r\ncuda.select_device(1)\r\n\r\n@cuda.jit\r\ndef CudaSquare(x):\r\n i, j = cuda.grid(2)\r\n x[i][j] *= x[i][j]\r\n\r\n\r\n#numba的矢量化加速\r\nfrom math import sin\r\n@nb.vectorize()\r\ndef nb_vec_sin(a):\r\n return sin(a)\r\n```\r\n\r\n\r\n### 3、CuPy\r\nCuPy 是一个借助 CUDA GPU 库在英伟达 GPU 上实现 Numpy 数组的库。基于 Numpy 数组的实现,GPU 自身具有的多个 CUDA 核心可以促成更好的并行加速。\r\n```\r\n# pip install cupy\r\nimport numpy as np\r\nimport cupy as cp\r\nimport time\r\n\r\n### numpy\r\ns = time.time()\r\nx_cpu = np.ones((1000,1000,1000))\r\ne = time.time()\r\nprint(e - s)\r\n\r\n### CuPy \r\ns = time.time()\r\nx_gpu = cp.ones((1000,1000,1000))\r\ne = time.time()\r\nprint(e - s)\r\n```\r\n上述代码,Numpy 创建(1000, 1000, 1000)的数组用了 1.68 秒,而 CuPy 仅用了 0.16 秒,实现了 10.5 倍的加速。随着数据量的猛增,CuPy的性能提升会更为明显。\r\n\r\n### 4、pandas使用技巧\r\n```更多pandas性能提升技巧请戳官方文档:https://pandas.pydata.org/pandas-docs/stable/user_guide/enhancingperf.html```\r\n#### 4.1 按行迭代优化\r\n我们按行对dataframe进行迭代,一般我们会用iterrows这个函数。在新版的pandas中,提供了一个更快的itertuples函数,如下可以看到速度快了几十倍。\r\n```\r\nimport pandas as pd\r\nimport numpy as np\r\nimport time\r\ndf = pd.DataFrame({'a': np.random.randn(100000),\r\n 'b': np.random.randn(100000),\r\n 'N': np.random.randint(100, 1000, (100000)),\r\n 'x': np.random.randint(1, 10, (100000))})\r\n\r\n%%timeit\r\na2=[]\r\nfor row in df.itertuples():\r\n temp=getattr(row, 'a')\r\n a2.append(temp*temp)\r\ndf['a2']=a2\r\n%%timeit\r\na2=[]\r\nfor index,row in df.iterrows():\r\n temp=row['a']\r\n a2.append(temp*temp)\r\ndf['a2']=a2 \r\n\r\n\r\n```\r\n\r\n#### 4.2 apply、applymap优化\r\n当对于每行执行类似的操作时,用循环逐行处理效率很低。这时可以用apply或applymap搭配函数操作,其中apply是可用于逐行计算,而applymap可以做更细粒度的逐个元素的计算。\r\n```\r\n# 列a、列b逐行进行某一函数计算\r\ndf['a3']=df.apply( lambda row: row['a']*row['b'],axis=1)\r\n# 逐个元素保留两位小数\r\ndf.applymap(lambda x: \"%.2f\" % x)\r\n```\r\n\r\n#### 4.3 聚合函数agg优化\r\n\r\n对于某列将进行聚合后,使用内置的函数比自定义函数效率更高,如下示例速度加速3倍\r\n```\r\n%timeit df.groupby(\"x\")['a'].agg(lambda x:x.sum())\r\n\r\n%timeit df.groupby(\"x\")['a'].agg(sum)\r\n\r\n%timeit df.groupby(\"x\")['a'].agg(np.sum)\r\n```\r\n\r\n\r\n#### 4.4 文件操作\r\npandas读取文件,pkl格式的数据的读取速度最快,其次是hdf格式的数据,再者是读取csv格式数据,而xlsx的读取是比较慢的。但是存取csv有个好处是,这个数据格式通用性更好,占用内存硬盘资源也比较少。此外,对于大文件,csv还可以对文件分块、选定某几列、指定数据类型做读取。\r\n\r\n#### 4.5 pandas.eval\r\npandas.eval 是基于第一节提到的numexpr,pandas也是基于numpy开发的,numexpr同样可以被用来对pandas加速)。使用eval表达式的一个经验是数据超过 10,000 行的情况下使用会有明显优化效果。\r\n```\r\nimport pandas as pd \r\nnrows, ncols = 20000, 100\r\ndf1, df2, df3, df4 = [pd.DataFrame(np.random.randn(nrows, ncols)) for _ in range(4)]\r\n\r\nprint('pd')\r\n%timeit df1 + df2 + df3 + df4\r\nprint('pd.eval')\r\n%timeit pd.eval(\"df1 + df2 + df3 + df4\")\r\n```\r\n\r\n\r\n### 5、Cython优化\r\nCython是一个基于C语言的Python 编译器,在一些计算量大的程序中,可以Cython来实现相当大的加速。考虑大部分人可能都不太了解复杂的cython语句,下面介绍下Cython的简易版使用技巧。通过在Ipython加入 Cython 魔术函数`%load_ext Cython`,如下示例就可以加速了一倍。进一步再借助更高级的cython语句,还是可以比Python快个几十上百倍。\r\n\r\n```\r\n%%cython\r\ndef f_plain(x):\r\n return x * (x - 1)\r\ndef integrate_f_plain(a, b, N):\r\n s = 0\r\n dx = (b - a) / N\r\n for i in range(N):\r\n s += f_plain(a + i * dx)\r\n return s * dx\r\n```\r\n\r\n\r\n\r\n\r\n\r\n### 6、swifter\r\nswifter是pandas的插件,可以直接在pandas的数据上操作。Swifter的优化方法检验计算是否可以矢量化或者并行化处理,以提高性能。如常见的apply就可以通过swifter并行处理。\r\n```\r\nimport pandas as pd\r\nimport swifter\r\n\r\ndf.swifter.apply(lambda x: x.sum() - x.min())\r\n```\r\n\r\n### 7、Modin\r\nModin后端使用dask或者ray(dask是类似pandas库的功能,可以实现并行读取运行),是个支持分布式运行的类pandas库,简单通过更改一行代码`import modin.pandas as pd`就可以优化 pandas,常用的内置的read_csv、concat、apply都有不错的加速。注:并行处理的开销会使小数据集的处理速度变慢。\r\n\r\n```\r\n!pip install modin\r\nimport pandas\r\nimport modin.pandas as pd\r\nimport time\r\n\r\n## pandas\r\n\r\npandas_df = pandas.DataFrame({'a': np.random.randn(10000000),\r\n 'b': np.random.randn(10000000),\r\n 'N': np.random.randint(100, 10000, (10000000)),\r\n 'x': np.random.randint(1, 1000, (10000000))})\r\n\r\n\r\n\r\nstart = time.time()\r\n\r\nbig_pandas_df = pandas.concat([pandas_df for _ in range(25)])\r\n\r\nend = time.time()\r\npandas_duration = end - start\r\nprint(\"Time to concat with pandas: {} seconds\".format(round(pandas_duration, 3)))\r\n\r\n#### modin.pandas\r\nmodin_df = pd.DataFrame({'a': np.random.randn(10000000),\r\n 'b': np.random.randn(10000000),\r\n 'N': np.random.randint(100, 10000, (10000000)),\r\n 'x': np.random.randint(1, 1000, (10000000))})\r\n\r\nstart = time.time()\r\nbig_modin_df = pd.concat([modin_df for _ in range(25)])\r\n\r\nend = time.time()\r\nmodin_duration = end - start\r\nprint(\"Time to concat with Modin: {} seconds\".format(round(modin_duration, 3)))\r\n\r\nprint(\"Modin is {}x faster than pandas at `concat`!\".format(round(pandas_duration / modin_duration, 2)))\r\n```\r\n\r\n\r\n(END)\r\n---\r\n文章首发公众号“算法进阶”,欢迎关注。公众号阅读原文可访问文章[相关代码及资料](https://github.com/aialgorithm/Blog)","author":{"url":"https://github.com/aialgorithm","@type":"Person","name":"aialgorithm"},"datePublished":"2022-04-12T06:51:56.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":0},"url":"https://github.com/48/Blog/issues/48"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:0b31194c-f613-0813-c4e4-4804c634fa04 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | 93D0:36DBB6:4771CD:648DA5:696A21DA |
| html-safe-nonce | 007c9871e6f37c5c9442f87c152d9db46e89e840eb9d1c194d56f988e0dfd71c |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiI5M0QwOjM2REJCNjo0NzcxQ0Q6NjQ4REE1OjY5NkEyMURBIiwidmlzaXRvcl9pZCI6IjExMzI0MDM0NzI2NDQ4NDE5NDYiLCJyZWdpb25fZWRnZSI6ImlhZCIsInJlZ2lvbl9yZW5kZXIiOiJpYWQifQ== |
| visitor-hmac | c7b1f5a1d54101389877574a8fd3cb28de0c47f78e1cdb5c5518d737d90aab49 |
| hovercard-subject-tag | issue:1201225687 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/aialgorithm/Blog/48/issue_layout |
| twitter:image | https://opengraph.githubassets.com/ec3e90037c7bfc21c24dbea5e1e4935614993c8d4427b325e51da468f78e918f/aialgorithm/Blog/issues/48 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/ec3e90037c7bfc21c24dbea5e1e4935614993c8d4427b325e51da468f78e918f/aialgorithm/Blog/issues/48 |
| og:image:alt | pandas、numpy是Python数据科学中非常常用的库,numpy是Python的数值计算扩展,专门用来处理矩阵,它的运算效率比列表更高效。pandas是基于numpy的数据处理工具,能更方便的操作大型表格类型的数据集。 但是,随着数据量的剧增,有时numpy和pandas的速度就成瓶颈。如下我们会介绍一些优化秘籍:里面包含 代码上面的优化,以及可以无脑使用的性能优化扩展包。 1、Nu... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | aialgorithm |
| hostname | github.com |
| expected-hostname | github.com |
| None | 014f3d193f36b7d393f88ca22d06fbacd370800b40a547c1ea67291e02dc8ea3 |
| turbo-cache-control | no-preview |
| go-import | github.com/aialgorithm/Blog git https://github.com/aialgorithm/Blog.git |
| octolytics-dimension-user_id | 33707637 |
| octolytics-dimension-user_login | aialgorithm |
| octolytics-dimension-repository_id | 147093233 |
| octolytics-dimension-repository_nwo | aialgorithm/Blog |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 147093233 |
| octolytics-dimension-repository_network_root_nwo | aialgorithm/Blog |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | d515f6f09fa57a93bf90355cb894eb84ca4f458f |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width