{"id":1851,"date":"2025-03-22T11:28:09","date_gmt":"2025-03-22T10:28:09","guid":{"rendered":"https:\/\/lorentzen.ch\/?p=1851"},"modified":"2025-03-30T12:14:15","modified_gmt":"2025-03-30T10:14:15","slug":"converting-csv-to-parquet","status":"publish","type":"post","link":"https:\/\/lorentzen.ch\/index.php\/2025\/03\/22\/converting-csv-to-parquet\/","title":{"rendered":"Converting arbitrarily large CSVs to Parquet with Python"},"content":{"rendered":"\n<p>Conversion from CSV to Parquet in streaming mode? No problem for the two power houses <strong><a href=\"https:\/\/pola.rs\/\">Polars<\/a><\/strong> and <a href=\"https:\/\/duckdb.org\/\">DuckDB<\/a>. We can even throw in some data preprocessing steps in-between, like column selection, data filters, or sorts.<\/p>\n\n\n\n<p>Edit: Streaming writing (or &#8220;lazy sinking&#8221;) of data with Polars was introduced with release 1.25.2 in March 2025, thanks Christian for pointing this out.<\/p>\n\n\n\n<p><code>pip install polars<\/code><\/p>\n\n\n\n<p><img decoding=\"async\" src=\"https:\/\/lorentzen.ch\/wp-content\/uploads\/2025\/03\/image-3.png\" alt=\"\"><\/p>\n\n\n\n<p><code><code>pip install duckdb<\/code><\/code><\/p>\n\n\n\n<p><br><img decoding=\"async\" src=\"https:\/\/lorentzen.ch\/wp-content\/uploads\/2025\/03\/image-2.png\" alt=\"\"><\/p>\n\n\n\n<p>Run times are on a normal laptop, dedicating 8 threads to the crunching.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Let&#8217;s generate a 2 GB csv file first<\/h2>\n\n\n<div class=\"wp-block-ub-tabbed-content wp-block-ub-tabbed-content-holder wp-block-ub-tabbed-content-horizontal-holder-mobile wp-block-ub-tabbed-content-horizontal-holder-tablet\" id=\"ub-tabbed-content-56eb16d2-852b-4a36-b666-eaded0678dc7\" style=\"\">\n\t\t\t<div class=\"wp-block-ub-tabbed-content-tab-holder horizontal-tab-width-mobile horizontal-tab-width-tablet\">\n\t\t\t\t<div role=\"tablist\" class=\"wp-block-ub-tabbed-content-tabs-title wp-block-ub-tabbed-content-tabs-title-mobile-horizontal-tab wp-block-ub-tabbed-content-tabs-title-tablet-horizontal-tab\" style=\"justify-content: flex-start; \"><div role=\"tab\" id=\"ub-tabbed-content-56eb16d2-852b-4a36-b666-eaded0678dc7-tab-0\" aria-controls=\"ub-tabbed-content-56eb16d2-852b-4a36-b666-eaded0678dc7-panel-0\" aria-selected=\"true\" class=\"wp-block-ub-tabbed-content-tab-title-wrap active\" style=\"--ub-tabbed-title-background-color: #6d6d6d; --ub-tabbed-active-title-color: inherit; --ub-tabbed-active-title-background-color: #6d6d6d; text-align: center; \" tabindex=\"-1\">\n\t\t\t\t<div class=\"wp-block-ub-tabbed-content-tab-title\">Python<\/div>\n\t\t\t<\/div><\/div>\n\t\t\t<\/div>\n\t\t\t<div class=\"wp-block-ub-tabbed-content-tabs-content\" style=\"\"><div role=\"tabpanel\" class=\"wp-block-ub-tabbed-content-tab-content-wrap active\" id=\"ub-tabbed-content-56eb16d2-852b-4a36-b666-eaded0678dc7-panel-0\" aria-labelledby=\"ub-tabbed-content-56eb16d2-852b-4a36-b666-eaded0678dc7-tab-0\" tabindex=\"0\">\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting='{\"showPanel\":true,\"languageLabel\":\"language\",\"fullScreenButton\":true,\"copyButton\":true,\"mode\":\"python\",\"mime\":\"text\/x-python\",\"theme\":\"material\",\"lineNumbers\":false,\"styleActiveLine\":false,\"lineWrapping\":false,\"readOnly\":true,\"fileName\":\"\",\"language\":\"Python\",\"maxHeight\":\"400px\",\"modeName\":\"python\"}'>import duckdb  # 1.2.1\nimport numpy as np  # 1.26.4\nimport polars as pl  # 1.25.2\n\nn = 100_000_000\n\nrng = np.random.default_rng(42)\n\ndf = pl.DataFrame(\n    {\n        \"X\": rng.choice([\"a\", \"b\", \"c\"], n),\n        \"Y\": rng.uniform(0, 1, n),\n        \"Z\": rng.choice([1, 2, 3, 4, 5], n),\n    }\n)\n\ndf.write_csv(\"data.csv\")<\/pre><\/div>\n\n<\/div><\/div>\n\t\t<\/div>\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"682\" height=\"27\" src=\"https:\/\/lorentzen.ch\/wp-content\/uploads\/2025\/03\/image-1.png\" alt=\"\" class=\"wp-image-1852\" srcset=\"https:\/\/lorentzen.ch\/wp-content\/uploads\/2025\/03\/image-1.png 682w, https:\/\/lorentzen.ch\/wp-content\/uploads\/2025\/03\/image-1-300x12.png 300w\" sizes=\"auto, (max-width: 682px) 100vw, 682px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Polars<\/h2>\n\n\n\n<p>Let&#8217;s use Polars in Lazy mode to connect to the CSV, apply some data operations, and stream the result into a Parquet file. <\/p>\n\n\n<div class=\"wp-block-ub-tabbed-content wp-block-ub-tabbed-content-holder wp-block-ub-tabbed-content-horizontal-holder-mobile wp-block-ub-tabbed-content-horizontal-holder-tablet\" id=\"ub-tabbed-content-036d72cf-5c74-476a-9ae3-1642330b19f5\" style=\"\">\n\t\t\t<div class=\"wp-block-ub-tabbed-content-tab-holder horizontal-tab-width-mobile horizontal-tab-width-tablet\">\n\t\t\t\t<div role=\"tablist\" class=\"wp-block-ub-tabbed-content-tabs-title wp-block-ub-tabbed-content-tabs-title-mobile-horizontal-tab wp-block-ub-tabbed-content-tabs-title-tablet-horizontal-tab\" style=\"justify-content: flex-start; \"><div role=\"tab\" id=\"ub-tabbed-content-036d72cf-5c74-476a-9ae3-1642330b19f5-tab-0\" aria-controls=\"ub-tabbed-content-036d72cf-5c74-476a-9ae3-1642330b19f5-panel-0\" aria-selected=\"true\" class=\"wp-block-ub-tabbed-content-tab-title-wrap active\" style=\"--ub-tabbed-title-background-color: #6d6d6d; --ub-tabbed-active-title-color: inherit; --ub-tabbed-active-title-background-color: #6d6d6d; text-align: center; \" tabindex=\"-1\">\n\t\t\t\t<div class=\"wp-block-ub-tabbed-content-tab-title\">Python<\/div>\n\t\t\t<\/div><\/div>\n\t\t\t<\/div>\n\t\t\t<div class=\"wp-block-ub-tabbed-content-tabs-content\" style=\"\"><div role=\"tabpanel\" class=\"wp-block-ub-tabbed-content-tab-content-wrap active\" id=\"ub-tabbed-content-036d72cf-5c74-476a-9ae3-1642330b19f5-panel-0\" aria-labelledby=\"ub-tabbed-content-036d72cf-5c74-476a-9ae3-1642330b19f5-tab-0\" tabindex=\"0\">\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting='{\"showPanel\":true,\"languageLabel\":\"language\",\"fullScreenButton\":true,\"copyButton\":true,\"mode\":\"python\",\"mime\":\"text\/x-python\",\"theme\":\"material\",\"lineNumbers\":false,\"styleActiveLine\":false,\"lineWrapping\":false,\"readOnly\":true,\"fileName\":\"\",\"language\":\"Python\",\"maxHeight\":\"400px\",\"modeName\":\"python\"}'># Native API with POLARS_MAX_THREADS = 8\n(\n    pl.scan_csv(\"data.csv\")\n    .filter(pl.col(\"X\") == \"a\")\n    .drop(\"X\")\n    .sort([\"Y\", \"Z\"])\n    .sink_parquet(\"data.parquet\", row_group_size=100_000)  # \"zstd\" compression\n)\n# 3.5 s<\/pre><\/div>\n\n<\/div><\/div>\n\t\t<\/div>\n\n\n<p>In case you prefer to write SQL code, you can alternatively use the SQL API of Polars. Curiously, run time is substantially longer: <\/p>\n\n\n<div class=\"wp-block-ub-tabbed-content wp-block-ub-tabbed-content-holder wp-block-ub-tabbed-content-horizontal-holder-mobile wp-block-ub-tabbed-content-horizontal-holder-tablet\" id=\"ub-tabbed-content-b1ba79df-f9d7-4a2d-b312-4948dfc542d8\" style=\"\">\n\t\t\t<div class=\"wp-block-ub-tabbed-content-tab-holder horizontal-tab-width-mobile horizontal-tab-width-tablet\">\n\t\t\t\t<div role=\"tablist\" class=\"wp-block-ub-tabbed-content-tabs-title wp-block-ub-tabbed-content-tabs-title-mobile-horizontal-tab wp-block-ub-tabbed-content-tabs-title-tablet-horizontal-tab\" style=\"justify-content: flex-start; \"><div role=\"tab\" id=\"ub-tabbed-content-b1ba79df-f9d7-4a2d-b312-4948dfc542d8-tab-0\" aria-controls=\"ub-tabbed-content-b1ba79df-f9d7-4a2d-b312-4948dfc542d8-panel-0\" aria-selected=\"true\" class=\"wp-block-ub-tabbed-content-tab-title-wrap active\" style=\"--ub-tabbed-title-background-color: #6d6d6d; --ub-tabbed-active-title-color: inherit; --ub-tabbed-active-title-background-color: #6d6d6d; text-align: center; \" tabindex=\"-1\">\n\t\t\t\t<div class=\"wp-block-ub-tabbed-content-tab-title\">Python<\/div>\n\t\t\t<\/div><\/div>\n\t\t\t<\/div>\n\t\t\t<div class=\"wp-block-ub-tabbed-content-tabs-content\" style=\"\"><div role=\"tabpanel\" class=\"wp-block-ub-tabbed-content-tab-content-wrap active\" id=\"ub-tabbed-content-b1ba79df-f9d7-4a2d-b312-4948dfc542d8-panel-0\" aria-labelledby=\"ub-tabbed-content-b1ba79df-f9d7-4a2d-b312-4948dfc542d8-tab-0\" tabindex=\"0\">\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting='{\"showPanel\":true,\"languageLabel\":\"language\",\"fullScreenButton\":true,\"copyButton\":true,\"mode\":\"python\",\"mime\":\"text\/x-python\",\"theme\":\"material\",\"lineNumbers\":false,\"styleActiveLine\":false,\"lineWrapping\":false,\"readOnly\":true,\"fileName\":\"\",\"language\":\"Python\",\"maxHeight\":\"400px\",\"modeName\":\"python\"}'># Via SQL API (slower!?)\n(\n    pl.scan_csv(\"data.csv\")\n    .sql(\"SELECT Y, Z FROM self WHERE X == 'a' ORDER BY Y, Z\")\n    .sink_parquet(\"data.parquet\", row_group_size=100_000)\n)\n\n# 6.8 s<\/pre><\/div>\n\n<\/div><\/div>\n\t\t<\/div>\n\n\n<p>In both cases, the result looks as expected, and the resulting Parquet file is about 170 MB large.<\/p>\n\n\n<div class=\"wp-block-ub-tabbed-content wp-block-ub-tabbed-content-holder wp-block-ub-tabbed-content-horizontal-holder-mobile wp-block-ub-tabbed-content-horizontal-holder-tablet\" id=\"ub-tabbed-content-b8c70eb0-e04d-43c6-aa35-d3e41f3d0f03\" style=\"\">\n\t\t\t<div class=\"wp-block-ub-tabbed-content-tab-holder horizontal-tab-width-mobile horizontal-tab-width-tablet\">\n\t\t\t\t<div role=\"tablist\" class=\"wp-block-ub-tabbed-content-tabs-title wp-block-ub-tabbed-content-tabs-title-mobile-horizontal-tab wp-block-ub-tabbed-content-tabs-title-tablet-horizontal-tab\" style=\"justify-content: flex-start; \"><div role=\"tab\" id=\"ub-tabbed-content-b8c70eb0-e04d-43c6-aa35-d3e41f3d0f03-tab-0\" aria-controls=\"ub-tabbed-content-b8c70eb0-e04d-43c6-aa35-d3e41f3d0f03-panel-0\" aria-selected=\"true\" class=\"wp-block-ub-tabbed-content-tab-title-wrap active\" style=\"--ub-tabbed-title-background-color: #6d6d6d; --ub-tabbed-active-title-color: inherit; --ub-tabbed-active-title-background-color: #6d6d6d; text-align: center; \" tabindex=\"-1\">\n\t\t\t\t<div class=\"wp-block-ub-tabbed-content-tab-title\">Python<\/div>\n\t\t\t<\/div><\/div>\n\t\t\t<\/div>\n\t\t\t<div class=\"wp-block-ub-tabbed-content-tabs-content\" style=\"\"><div role=\"tabpanel\" class=\"wp-block-ub-tabbed-content-tab-content-wrap active\" id=\"ub-tabbed-content-b8c70eb0-e04d-43c6-aa35-d3e41f3d0f03-panel-0\" aria-labelledby=\"ub-tabbed-content-b8c70eb0-e04d-43c6-aa35-d3e41f3d0f03-tab-0\" tabindex=\"0\">\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting='{\"showPanel\":true,\"languageLabel\":\"language\",\"fullScreenButton\":true,\"copyButton\":true,\"mode\":\"python\",\"mime\":\"text\/x-python\",\"theme\":\"material\",\"lineNumbers\":false,\"styleActiveLine\":false,\"lineWrapping\":false,\"readOnly\":true,\"fileName\":\"\",\"language\":\"Python\",\"maxHeight\":\"400px\",\"modeName\":\"python\"}'>pl.scan_parquet(\"data.parquet\").head(5).collect()\n\n# Output\n        Y   Z\n      f64 i64\n3.7796e-8\t4\n5.0273e-8\t5\n5.7652e-8\t4\n8.0578e-8\t3\n8.1598e-8\t4<\/pre><\/div>\n\n<\/div><\/div>\n\t\t<\/div>\n\n\n<h2 class=\"wp-block-heading\">DuckDB<\/h2>\n\n\n\n<p>As an alternative, we use <a href=\"https:\/\/duckdb.org\/\">DuckDB<\/a>. Thread pool size and RAM limit can be set on the fly. Setting a low memory limit (e.g., 500 MB) will lead to longer run times, but it works.<\/p>\n\n\n<div class=\"wp-block-ub-tabbed-content wp-block-ub-tabbed-content-holder wp-block-ub-tabbed-content-horizontal-holder-mobile wp-block-ub-tabbed-content-horizontal-holder-tablet\" id=\"ub-tabbed-content-1704d92c-e6f8-47d8-93f8-5d8e9fd89456\" style=\"\">\n\t\t\t<div class=\"wp-block-ub-tabbed-content-tab-holder horizontal-tab-width-mobile horizontal-tab-width-tablet\">\n\t\t\t\t<div role=\"tablist\" class=\"wp-block-ub-tabbed-content-tabs-title wp-block-ub-tabbed-content-tabs-title-mobile-horizontal-tab wp-block-ub-tabbed-content-tabs-title-tablet-horizontal-tab\" style=\"justify-content: flex-start; \"><div role=\"tab\" id=\"ub-tabbed-content-1704d92c-e6f8-47d8-93f8-5d8e9fd89456-tab-0\" aria-controls=\"ub-tabbed-content-1704d92c-e6f8-47d8-93f8-5d8e9fd89456-panel-0\" aria-selected=\"true\" class=\"wp-block-ub-tabbed-content-tab-title-wrap active\" style=\"--ub-tabbed-title-background-color: #6d6d6d; --ub-tabbed-active-title-color: inherit; --ub-tabbed-active-title-background-color: #6d6d6d; text-align: center; \" tabindex=\"-1\">\n\t\t\t\t<div class=\"wp-block-ub-tabbed-content-tab-title\">Python<\/div>\n\t\t\t<\/div><\/div>\n\t\t\t<\/div>\n\t\t\t<div class=\"wp-block-ub-tabbed-content-tabs-content\" style=\"\"><div role=\"tabpanel\" class=\"wp-block-ub-tabbed-content-tab-content-wrap active\" id=\"ub-tabbed-content-1704d92c-e6f8-47d8-93f8-5d8e9fd89456-panel-0\" aria-labelledby=\"ub-tabbed-content-1704d92c-e6f8-47d8-93f8-5d8e9fd89456-tab-0\" tabindex=\"0\">\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting='{\"showPanel\":true,\"languageLabel\":\"language\",\"fullScreenButton\":true,\"copyButton\":true,\"mode\":\"python\",\"mime\":\"text\/x-python\",\"theme\":\"material\",\"lineNumbers\":false,\"styleActiveLine\":false,\"lineWrapping\":false,\"readOnly\":true,\"fileName\":\"\",\"language\":\"Python\",\"maxHeight\":\"400px\",\"modeName\":\"python\"}'>con = duckdb.connect(config={\"threads\": 8, \"memory_limit\": \"4GB\"})\n\ncon.sql(\n    \"\"\"\n    COPY (\n        SELECT Y, Z\n        FROM 'data.csv'\n        WHERE X == 'a'\n        ORDER BY Y, Z\n    ) TO 'data.parquet' (FORMAT parquet, COMPRESSION zstd, ROW_GROUP_SIZE 100_000)\n    \"\"\"\n)\n\n# 3.9 s<\/pre><\/div>\n\n<\/div><\/div>\n\t\t<\/div>\n\n\n<p>Again, the output looks as expected. The Parquet file is again 170 MB large, thanks to using the same compression (&#8220;zstd&#8221;) as with Polars..<\/p>\n\n\n<div class=\"wp-block-ub-tabbed-content wp-block-ub-tabbed-content-holder wp-block-ub-tabbed-content-horizontal-holder-mobile wp-block-ub-tabbed-content-horizontal-holder-tablet\" id=\"ub-tabbed-content-73445bcc-a470-40ed-88fd-4ca48440c21c\" style=\"\">\n\t\t\t<div class=\"wp-block-ub-tabbed-content-tab-holder horizontal-tab-width-mobile horizontal-tab-width-tablet\">\n\t\t\t\t<div role=\"tablist\" class=\"wp-block-ub-tabbed-content-tabs-title wp-block-ub-tabbed-content-tabs-title-mobile-horizontal-tab wp-block-ub-tabbed-content-tabs-title-tablet-horizontal-tab\" style=\"justify-content: flex-start; \"><div role=\"tab\" id=\"ub-tabbed-content-73445bcc-a470-40ed-88fd-4ca48440c21c-tab-0\" aria-controls=\"ub-tabbed-content-73445bcc-a470-40ed-88fd-4ca48440c21c-panel-0\" aria-selected=\"true\" class=\"wp-block-ub-tabbed-content-tab-title-wrap active\" style=\"--ub-tabbed-title-background-color: #6d6d6d; --ub-tabbed-active-title-color: inherit; --ub-tabbed-active-title-background-color: #6d6d6d; text-align: center; \" tabindex=\"-1\">\n\t\t\t\t<div class=\"wp-block-ub-tabbed-content-tab-title\">Python<\/div>\n\t\t\t<\/div><\/div>\n\t\t\t<\/div>\n\t\t\t<div class=\"wp-block-ub-tabbed-content-tabs-content\" style=\"\"><div role=\"tabpanel\" class=\"wp-block-ub-tabbed-content-tab-content-wrap active\" id=\"ub-tabbed-content-73445bcc-a470-40ed-88fd-4ca48440c21c-panel-0\" aria-labelledby=\"ub-tabbed-content-73445bcc-a470-40ed-88fd-4ca48440c21c-tab-0\" tabindex=\"0\">\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting='{\"showPanel\":true,\"languageLabel\":\"language\",\"fullScreenButton\":true,\"copyButton\":true,\"mode\":\"python\",\"mime\":\"text\/x-python\",\"theme\":\"material\",\"lineNumbers\":false,\"styleActiveLine\":false,\"lineWrapping\":false,\"readOnly\":true,\"fileName\":\"\",\"language\":\"Python\",\"maxHeight\":\"400px\",\"modeName\":\"python\"}'>con.sql(\"SELECT * FROM 'data.parquet' LIMIT 5\")\n\n# Output\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502           Y            \u2502   Z   \u2502\n\u2502         double         \u2502 int64 \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502  3.779571322581887e-08 \u2502     4 \u2502\n\u2502 5.0273087692787044e-08 \u2502     5 \u2502\n\u2502   5.76523543349694e-08 \u2502     4 \u2502\n\u2502  8.057776434977626e-08 \u2502     3 \u2502\n\u2502  8.159834352650108e-08 \u2502     4 \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/pre><\/div>\n\n<\/div><\/div>\n\t\t<\/div>\n\n\n<h2 class=\"wp-block-heading\">Final words<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>With Polars or DuckDB, conversion of CSVs to Parquet is easy and fast, even in larger-than-RAM situations.<\/li>\n\n\n\n<li>We can apply filters, selects, sorts etc. on the fly.<\/li>\n<\/ul>\n\n\n\n<p><a href=\"https:\/\/github.com\/lorentzenchr\/notebooks\/blob\/master\/blogposts\/2025-03-22%20csv%20to%20parquet.ipynb\">Python notebook<\/a><\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>How to convert that huge csv to parquet?<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[27,16,17],"tags":[6],"class_list":["post-1851","post","type-post","status-publish","format-standard","hentry","category-data","category-machine-learning","category-programming","tag-python"],"featured_image_src":null,"author_info":{"display_name":"Michael Mayer","author_link":"https:\/\/lorentzen.ch\/index.php\/author\/michael\/"},"_links":{"self":[{"href":"https:\/\/lorentzen.ch\/index.php\/wp-json\/wp\/v2\/posts\/1851","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/lorentzen.ch\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/lorentzen.ch\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/lorentzen.ch\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/lorentzen.ch\/index.php\/wp-json\/wp\/v2\/comments?post=1851"}],"version-history":[{"count":4,"href":"https:\/\/lorentzen.ch\/index.php\/wp-json\/wp\/v2\/posts\/1851\/revisions"}],"predecessor-version":[{"id":1876,"href":"https:\/\/lorentzen.ch\/index.php\/wp-json\/wp\/v2\/posts\/1851\/revisions\/1876"}],"wp:attachment":[{"href":"https:\/\/lorentzen.ch\/index.php\/wp-json\/wp\/v2\/media?parent=1851"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/lorentzen.ch\/index.php\/wp-json\/wp\/v2\/categories?post=1851"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/lorentzen.ch\/index.php\/wp-json\/wp\/v2\/tags?post=1851"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}