{"id":304006,"date":"2020-05-21T15:00:57","date_gmt":"2020-05-21T15:00:57","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=304006"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=304006","title":{"rendered":"\u0412\u044b\u0441\u043e\u043a\u043e\u0441\u043a\u043e\u0440\u043e\u0441\u0442\u043d\u043e\u0439 Apache Parquet \u043d\u0430 Python \u0441 Apache Arrow"},"content":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/company\/otus\/blog\/503132\/\"><b><i>\u0412\u0441\u0435\u043c \u0441\u0430\u043b\u044e\u0442. \u0423\u0436\u0435 \u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u043d\u0435\u0434\u0435\u043b\u0435 \u0441\u0442\u0430\u0440\u0442\u0443\u044e\u0442 \u0437\u0430\u043d\u044f\u0442\u0438\u044f \u0432 \u043d\u043e\u0432\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u0435 \u043a\u0443\u0440\u0441\u0430 <a href=\"https:\/\/otus.pw\/KWqV\/\">\u00abData Engineer\u00bb<\/a>, \u0432 \u0441\u0432\u044f\u0437\u0438 \u0441 \u044d\u0442\u0438\u043c \u0434\u0435\u043b\u0438\u043c\u0441\u044f \u0441 \u0432\u0430\u043c\u0438 \u0435\u0449\u0435 \u043e\u0434\u043d\u0438\u043c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u043c \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u043e\u043c.<\/i><\/b><\/p>\n<hr>\n<p>  <i>\u041d\u0430 \u043f\u0440\u043e\u0442\u044f\u0436\u0435\u043d\u0438\u0438 \u0432\u0441\u0435\u0433\u043e \u043f\u0440\u043e\u0448\u043b\u043e\u0433\u043e \u0433\u043e\u0434\u0430 \u044f \u0440\u0430\u0431\u043e\u0442\u0430\u043b \u0441 \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u043e\u043c Apache Parquet \u043d\u0430\u0434 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435\u043c <a href=\"https:\/\/github.com\/apache\/parquet-cpp\">parquet-cpp<\/a> \u2014 \u043f\u0435\u0440\u0432\u043e\u043a\u043b\u0430\u0441\u0441\u043d\u043e\u0439 C++ Parquet \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f\/\u0437\u0430\u043f\u0438\u0441\u0438 \u0444\u0430\u0439\u043b\u043e\u0432, \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0435\u0439 \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0432 Python \u0438 \u0434\u0440\u0443\u0433\u0438\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438. <a href=\"https:\/\/github.com\/xhochy\">\u0423\u0432\u0435 \u041a\u043e\u0440\u043d<\/a> \u0438 \u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0438 Python \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0438 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044e \u0441 pandas \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u043a\u043e\u0434\u043e\u0432\u043e\u0439 \u0431\u0430\u0437\u044b Python (<code>pyarrow<\/code>) \u0432 Apache Arrow.<a name=\"habracut\"><\/a><\/p>\n<p>  \u042d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435\u043c \u043c\u043e\u0435\u0433\u043e <a href=\"https:\/\/wesmckinney.com\/blog\/outlook-for-2017\/\">\u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043f\u043b\u0430\u043d\u0430 \u043d\u0430 2017 \u0433\u043e\u0434<\/a>.<\/i><\/p>\n<h3>\u0414\u0438\u0437\u0430\u0439\u043d: \u0432\u044b\u0441\u043e\u043a\u043e\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043a\u043e\u043b\u043e\u043d\u043e\u0447\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 Python.<\/h3>\n<p>  C++ \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 <a href=\"https:\/\/github.com\/apache\/arrow\">Apache Arrow<\/a> \u0438 Parquet \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u043c\u0438 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u044f\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043b\u0438\u0441\u044c \u043d\u0430\u043c\u0438 \u0434\u043b\u044f \u0441\u043e\u0433\u043b\u0430\u0441\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b.<\/p>\n<ul>\n<li>\u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 C++ Arrow \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u044e\u0442 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u0430\u043c\u044f\u0442\u044c\u044e, <a href=\"https:\/\/wesmckinney.com\/blog\/python-hdfs-interfaces\/\">\u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0439 \u0432\u0432\u043e\u0434\/\u0432\u044b\u0432\u043e\u0434<\/a> (\u0444\u0430\u0439\u043b\u044b, memory map, HDFS), \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b \u043a\u043e\u043b\u043e\u043d\u043e\u0447\u043d\u044b\u0445 \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u0432 \u0432 \u043f\u0430\u043c\u044f\u0442\u0438 \u0438 \u0447\u0440\u0435\u0437\u0432\u044b\u0447\u0430\u0439\u043d\u043e \u0431\u044b\u0441\u0442\u0440\u044b\u0439 \u043e\u0431\u043c\u0435\u043d \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f\u043c\u0438 (IPC\/RPC). \u042f \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043a\u043e\u0441\u043d\u0443\u0441\u044c \u0441\u043b\u043e\u044f \u043e\u0431\u043c\u0435\u043d\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f\u043c\u0438 Arrow \u0432 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435.<\/li>\n<li>\u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 C++ Parquet \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0442 \u0437\u0430 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u0434\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u043e\u0432\u043e\u0433\u043e \u0444\u043e\u0440\u043c\u0430\u0442\u0430 Parquet. \u041c\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b\u0438 <code>libparquet_arrow<\/code> \u2014 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0442\u0440\u0430\u043d\u0437\u0438\u0442 \u043c\u0435\u0436\u0434\u0443 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0432 \u043f\u0430\u043c\u044f\u0442\u0438 Arrow \u0438 \u043d\u0438\u0437\u043a\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u044b\u043c\u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u043c\u0438 \u0447\u0442\u0435\u043d\u0438\u044f\/\u0437\u0430\u043f\u0438\u0441\u0438 Parquet.<\/li>\n<li>PyArrow \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 Python \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0434\u043b\u044f \u0432\u0441\u0435\u0433\u043e \u044d\u0442\u043e\u0433\u043e \u0438 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442<a href=\"https:\/\/wesmckinney.com\/blog\/high-perf-arrow-to-pandas\/\"> \u0431\u044b\u0441\u0442\u0440\u044b\u0435 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0432 pandas.DataFrame<\/a>.<\/li>\n<\/ul>\n<p>  \u041e\u0434\u043d\u043e\u0439 \u0438\u0437 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u0446\u0435\u043b\u0435\u0439 Apache Arrow \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u043c\u0435\u0436\u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f \u0442\u0440\u0430\u043d\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438 \u043a\u043e\u043b\u043e\u043d\u043e\u0447\u043d\u043e\u0439 \u043f\u0430\u043c\u044f\u0442\u0438.<\/p>\n<p>  \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u043c API Parquet \u0432 <a href=\"https:\/\/github.com\/apache\/arrow\/blob\/master\/python\/pyarrow\/parquet.py\">\u043a\u043e\u0434\u043e\u0432\u043e\u0439 \u0431\u0430\u0437\u0435 PyArrow<\/a>. \u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0432 <a href=\"https:\/\/conda-forge.github.io\/\">conda-forge<\/a> \u043f\u043e \u0430\u0434\u0440\u0435\u0441\u0443:<\/p>\n<pre><code class=\"python\">conda install pyarrow arrow-cpp parquet-cpp -c conda-forge<\/code><\/pre>\n<h3>\u0411\u0435\u043d\u0447\u043c\u0430\u0440\u043a\u0438: PyArrow \u0438 fastparquet<\/h3>\n<p>  \u0427\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 PyArrow, \u044f \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043b \u043d\u0430\u0431\u043e\u0440 \u0434\u0430\u043d\u043d\u044b\u0445 \u043e\u0431\u044a\u0435\u043c\u043e\u043c 512 \u043c\u0435\u0433\u0430\u0431\u0430\u0439\u0442 \u0441 \u0447\u0438\u0441\u043b\u043e\u0432\u044b\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u0443\u044e\u0442 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f Parquet. \u042f \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043b \u0434\u0432\u0430 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430 \u043d\u0430\u0431\u043e\u0440\u043e\u0432 \u0434\u0430\u043d\u043d\u044b\u0445:<\/p>\n<ul>\n<li><b>\u0421 \u0432\u044b\u0441\u043e\u043a\u043e\u0439 \u044d\u043d\u0442\u0440\u043e\u043f\u0438\u0435\u0439<\/b>: \u0432\u0441\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0444\u0430\u0439\u043b\u0435 (\u0437\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c \u043d\u0443\u043b\u0435\u0432\u044b\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439) \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b. \u042d\u0442\u043e\u0442 \u043d\u0430\u0431\u043e\u0440 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432\u0435\u0441\u0438\u0442 469 \u041c\u0411.<\/li>\n<li><b>\u0421 \u043d\u0438\u0437\u043a\u043e\u0439 \u044d\u043d\u0442\u0440\u043e\u043f\u0438\u0435\u0439<\/b>: \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u0443\u044e\u0442 \u0432\u044b\u0441\u043e\u043a\u0443\u044e \u0441\u0442\u0435\u043f\u0435\u043d\u044c \u043f\u043e\u0432\u0442\u043e\u0440\u0435\u043d\u0438\u044f. \u042d\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u043a\u043e\u0434\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0438 \u0441\u0436\u0438\u043c\u0430\u044e\u0442\u0441\u044f \u0434\u043e \u0432\u0435\u0441\u044c\u043c\u0430 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0430: \u0432\u0441\u0435\u0433\u043e 23 \u041c\u0411 \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c \u0441\u0436\u0430\u0442\u0438\u044f Snappy. \u0415\u0441\u043b\u0438 \u0432\u044b \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u0442\u0435 \u0444\u0430\u0439\u043b \u0441\u043e \u0441\u043b\u043e\u0432\u0430\u0440\u043d\u043e\u0439 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u043e\u0439, \u043e\u043d \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u0435\u0449\u0435 \u043c\u0435\u043d\u044c\u0448\u0435. \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0434\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0442\u0430\u043a\u0438\u0445 \u0444\u0430\u0439\u043b\u043e\u0432 \u0438\u043c\u0435\u0435\u0442 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u043f\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u0443, \u043d\u0435\u0436\u0435\u043b\u0438 \u043f\u043e \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f\u043c \u0432\u0432\u043e\u0434\u0430-\u0432\u044b\u0432\u043e\u0434\u0430, \u043e\u0431\u044b\u0447\u043d\u043e \u043c\u043e\u0436\u043d\u043e \u043e\u0436\u0438\u0434\u0430\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u0432\u044b\u0441\u043e\u043a\u0443\u044e \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u043d\u0443\u044e \u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u044c \u0434\u043b\u044f \u0444\u0430\u0439\u043b\u043e\u0432 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441 \u043d\u0438\u0437\u043a\u043e\u0439 \u044d\u043d\u0442\u0440\u043e\u043f\u0438\u0435\u0439.<\/li>\n<\/ul>\n<p>  \u042f \u0441\u043e\u0437\u0434\u0430\u043b \u044d\u0442\u0438 \u0444\u0430\u0439\u043b\u044b \u0432 \u0442\u0440\u0435\u0445 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0445 \u0441\u0442\u0438\u043b\u044f\u0445 \u0441\u0436\u0430\u0442\u0438\u044f: \u043d\u0435\u0441\u0436\u0430\u0442\u044b\u0435, snappy \u0438 gzip. \u0417\u0430\u0442\u0435\u043c \u044f \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u044e \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0432\u0440\u0435\u043c\u044f, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0435 \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f pandas DataFrame \u0441 \u0434\u0438\u0441\u043a\u0430.<\/p>\n<p>  <a href=\"https:\/\/github.com\/dask\/fastparquet\">fastparquet<\/a> \u2014 \u044d\u0442\u043e \u0431\u043e\u043b\u0435\u0435 \u043d\u043e\u0432\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0447\u0442\u0435\u043d\u0438\u044f\/\u0437\u0430\u043f\u0438\u0441\u0438 \u0444\u0430\u0439\u043b\u043e\u0432 Parquet \u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 Python, \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u0430\u044f \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0435 Dask. \u041e\u043d\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u0430 \u043d\u0430 Python \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 Numba Python-to-LLVM \u0434\u043b\u044f \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440 \u0434\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f Parquet. \u042f \u0442\u0430\u043a\u0436\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b \u0435\u0435, \u0447\u0442\u043e\u0431\u044b \u0441\u0440\u0430\u0432\u043d\u0438\u0442\u044c \u0441 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u044b\u043c\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f\u043c\u0438.<\/p>\n<p>  \u041a\u043e\u0434 \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f \u0444\u0430\u0439\u043b\u0430 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 <i>pandas.DataFrame<\/i> \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u0435\u043d:<\/p>\n<pre><code class=\"python\"># PyArrow import pyarrow.parquet as pq df1 = pq.read_table(path).to_pandas()  # fastparquet import fastparquet df2 = fastparquet.ParquetFile(path).to_pandas()<\/code><\/pre>\n<p>  \u0417\u0435\u043b\u0435\u043d\u044b\u0435 \u0441\u0442\u043e\u043b\u0431\u0446\u044b \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 PyArrow: \u0431\u043e\u043b\u0435\u0435 \u0434\u043b\u0438\u043d\u043d\u044b\u0435 \u0441\u0442\u043e\u043b\u0431\u0446\u044b \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442 \u043d\u0430 \u0431\u043e\u043b\u0435\u0435 \u0432\u044b\u0441\u043e\u043a\u0443\u044e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c\/\u0431\u043e\u043b\u0435\u0435 \u0432\u044b\u0441\u043e\u043a\u0443\u044e \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u043d\u0443\u044e \u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0445. \u0410\u043f\u043f\u0430\u0440\u0430\u0442\u043d\u043e\u0435 \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u0435 \u2014 \u043d\u043e\u0443\u0442\u0431\u0443\u043a Xeon E3-1505.<\/p>\n<p>  <b>\u042f \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u043b \u044d\u0442\u0438 \u0431\u0435\u043d\u0447\u043c\u0430\u0440\u043a\u0438 1 \u0444\u0435\u0432\u0440\u0430\u043b\u044f 2017 \u0433\u043e\u0434\u0430 \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0438 \u0441 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u043c\u0438 \u043a\u043e\u0434\u043e\u0432\u044b\u043c\u0438 \u0431\u0430\u0437\u0430\u043c\u0438.<\/b><\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/y8\/53\/co\/y853coezkvi3wxqcodpljkq-8ug.png\"><\/p>\n<h3>\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438<\/h3>\n<p>  \u041d\u0430\u043c \u043d\u0443\u0436\u043d\u0430 \u043f\u043e\u043c\u043e\u0449\u044c \u0441 \u0432\u0438\u043d\u0434\u043e\u0432\u044b\u043c\u0438 \u0441\u0431\u043e\u0440\u043a\u0430\u043c\u0438 \u0438 \u0443\u043f\u0430\u043a\u043e\u0432\u043a\u043e\u0439. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 conda-forge \u0432 \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0438 \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 \u043e\u0447\u0435\u043d\u044c \u043c\u043d\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438. \u0418 \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u043c\u044b \u0438\u0449\u0435\u043c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u043a\u0430\u043a \u043d\u0430 C++, \u0442\u0430\u043a \u0438 \u043d\u0430 Python, \u0434\u043b\u044f \u043a\u043e\u043d\u0442\u0440\u0438\u0431\u0443\u0446\u0438\u0439 \u0432 \u043a\u043e\u0434\u043e\u0432\u0443\u044e \u0431\u0430\u0437\u0443 \u0432\u043e\u043e\u0431\u0449\u0435 \u0432 \u0446\u0435\u043b\u043e\u043c.<\/p>\n<p>  \u0414\u043e \u0441\u0438\u0445 \u043f\u043e\u0440 \u043c\u044b \u0443\u0434\u0435\u043b\u044f\u043b\u0438 \u043e\u0441\u043e\u0431\u043e\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0444\u0430\u0439\u043b\u043e\u0432\u043e\u0433\u043e \u0444\u043e\u0440\u043c\u0430\u0442\u0430 \u0441 \u0432\u044b\u0441\u043e\u043a\u043e\u0439 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e \u0447\u0442\u0435\u043d\u0438\u044f \u0438 \u0437\u0430\u043f\u0438\u0441\u0438 \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u043d\u0430\u0431\u043e\u0440\u043e\u0432 \u0434\u0430\u043d\u043d\u044b\u0445. \u041c\u044b \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u043c \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442\u044c \u043a \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445 JSON-\u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 parquet-cpp, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f Arrow \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 \u0434\u043b\u044f \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445 \u043a\u043e\u043b\u043e\u043d\u043e\u0447\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<p>  \u041d\u0435\u0434\u0430\u0432\u043d\u043e <a href=\"https:\/\/github.com\/xhochy\">\u0423\u0432\u0435 \u041a\u043e\u0440\u043d<\/a> \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 <code>List<\/code> Arrow \u0432 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f\u0445 \u0432 pandas:<\/p>\n<pre><code class=\"python\">In [9]: arr = pa.from_pylist([[1,2,3], None, [1, 2], [], [4]])  In [10]: arr Out[10]: &lt;pyarrow.array.ListArray object at 0x7f562d551818&gt; [   [1,    2,    3],   NA,   [1,    2],   [],   [4] ]  In [11]: arr.type Out[11]: DataType(list&lt;item: int64&gt;)  In [12]: t = pa.Table.from_arrays([arr], ['col'])  In [13]: t.to_pandas() Out[13]:          col 0  [1, 2, 3] 1       None 2     [1, 2] 3         [] 4        [4]<\/code><\/pre>\n<h4>\u041a\u043e\u0434 \u0431\u0435\u043d\u0447\u043c\u0430\u0440\u043a\u0430<\/h4>\n<p>  <\/p>\n<pre><code class=\"python\">import os import time  import numpy as np import pandas as pd from pyarrow.compat import guid import pyarrow as pa import pyarrow.parquet as pq import fastparquet as fp  def generate_floats(n, pct_null, repeats=1):     nunique = int(n \/ repeats)     unique_values = np.random.randn(nunique)      num_nulls = int(nunique * pct_null)     null_indices = np.random.choice(nunique, size=num_nulls, replace=False)     unique_values[null_indices] = np.nan      return unique_values.repeat(repeats)  DATA_GENERATORS = {     'float64': generate_floats }  def generate_data(total_size, ncols, pct_null=0.1, repeats=1, dtype='float64'):     type_ = np.dtype('float64')     nrows = total_size \/ ncols \/ np.dtype(type_).itemsize      datagen_func = DATA_GENERATORS[dtype]      data = {         'c' + str(i): datagen_func(nrows, pct_null, repeats)         for i in range(ncols)     }     return pd.DataFrame(data)  def write_to_parquet(df, out_path, compression='SNAPPY'):     arrow_table = pa.Table.from_pandas(df)     if compression == 'UNCOMPRESSED':         compression = None     pq.write_table(arrow_table, out_path, use_dictionary=False,                    compression=compression)  def read_fastparquet(path):     return fp.ParquetFile(path).to_pandas()  def read_pyarrow(path, nthreads=1):     return pq.read_table(path, nthreads=nthreads).to_pandas()  MEGABYTE = 1 &lt;&lt; 20 DATA_SIZE = 512 * MEGABYTE NCOLS = 16  cases = {     'high_entropy': {         'pct_null': 0.1,         'repeats': 1     },     'low_entropy': {         'pct_null': 0.1,         'repeats': 1000     } }  def get_timing(f, path, niter):     start = time.clock_gettime(time.CLOCK_MONOTONIC)     for i in range(niter):         f(path)     elapsed = time.clock_gettime(time.CLOCK_MONOTONIC) - start     return elapsed  NITER = 5  results = []  readers = [     ('fastparquet', lambda path: read_fastparquet(path)),     ('pyarrow', lambda path: read_pyarrow(path)), ]  case_files = {}  for case, params in cases.items():     for compression in ['UNCOMPRESSED', 'SNAPPY', 'GZIP']:         path = '{0}_{1}.parquet'.format(case, compression)         df = generate_data(DATA_SIZE, NCOLS, **params)         write_to_parquet(df, path, compression=compression)         df = None         case_files[case, compression] = path  for case, params in cases.items():     for compression in ['UNCOMPRESSED', 'SNAPPY', 'GZIP']:         path = case_files[case, compression]          # prime the file cache         read_pyarrow(path)         read_pyarrow(path)          for reader_name, f in readers:             elapsed = get_timing(f, path, NITER) \/ NITER             result = case, compression, reader_name, elapsed             print(result)             results.append(result)<\/code><\/pre>\n<hr>\n<p>  <a href=\"https:\/\/otus.pw\/KWqV\/\">\u0423\u0441\u043f\u0435\u0442\u044c \u043d\u0430 \u043a\u0443\u0440\u0441.<\/a><\/p>\n<hr>\n<\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/company\/otus\/blog\/503132\/\"> https:\/\/habr.com\/ru\/company\/otus\/blog\/503132\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/company\/otus\/blog\/503132\/\"><b><i>\u0412\u0441\u0435\u043c \u0441\u0430\u043b\u044e\u0442. \u0423\u0436\u0435 \u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u043d\u0435\u0434\u0435\u043b\u0435 \u0441\u0442\u0430\u0440\u0442\u0443\u044e\u0442 \u0437\u0430\u043d\u044f\u0442\u0438\u044f \u0432 \u043d\u043e\u0432\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u0435 \u043a\u0443\u0440\u0441\u0430 <a href=\"https:\/\/otus.pw\/KWqV\/\">\u00abData Engineer\u00bb<\/a>, \u0432 \u0441\u0432\u044f\u0437\u0438 \u0441 \u044d\u0442\u0438\u043c \u0434\u0435\u043b\u0438\u043c\u0441\u044f \u0441 \u0432\u0430\u043c\u0438 \u0435\u0449\u0435 \u043e\u0434\u043d\u0438\u043c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u043c \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u043e\u043c.<\/i><\/b><\/p>\n<hr>\n<p>  <i>\u041d\u0430 \u043f\u0440\u043e\u0442\u044f\u0436\u0435\u043d\u0438\u0438 \u0432\u0441\u0435\u0433\u043e \u043f\u0440\u043e\u0448\u043b\u043e\u0433\u043e \u0433\u043e\u0434\u0430 \u044f \u0440\u0430\u0431\u043e\u0442\u0430\u043b \u0441 \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u043e\u043c Apache Parquet \u043d\u0430\u0434 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435\u043c <a href=\"https:\/\/github.com\/apache\/parquet-cpp\">parquet-cpp<\/a> \u2014 \u043f\u0435\u0440\u0432\u043e\u043a\u043b\u0430\u0441\u0441\u043d\u043e\u0439 C++ Parquet \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f\/\u0437\u0430\u043f\u0438\u0441\u0438 \u0444\u0430\u0439\u043b\u043e\u0432, \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0435\u0439 \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0432 Python \u0438 \u0434\u0440\u0443\u0433\u0438\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438. <a href=\"https:\/\/github.com\/xhochy\">\u0423\u0432\u0435 \u041a\u043e\u0440\u043d<\/a> \u0438 \u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0438 Python \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0438 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044e \u0441 pandas \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u043a\u043e\u0434\u043e\u0432\u043e\u0439 \u0431\u0430\u0437\u044b Python (<code>pyarrow<\/code>) \u0432 Apache Arrow.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-304006","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/304006","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=304006"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/304006\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=304006"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=304006"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=304006"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}