<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="../assets/xml/rss.xsl" media="all"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Blosc Home Page  (Posts about blosc2 concatenate performance)</title><link>https://blosc.org/</link><description></description><atom:link href="https://blosc.org/categories/blosc2-concatenate-performance.xml" rel="self" type="application/rss+xml"></atom:link><language>en</language><copyright>Contents © 2026 &lt;a href="mailto:blosc@blosc.org"&gt;The Blosc Developers&lt;/a&gt; </copyright><lastBuildDate>Wed, 10 Jun 2026 17:44:33 GMT</lastBuildDate><generator>Nikola (getnikola.com)</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>Efficient array concatenation launched in Blosc2</title><link>https://blosc.org/posts/blosc2-new-concatenate/</link><dc:creator>Francesc Alted</dc:creator><description>&lt;p&gt;&lt;strong&gt;Update (2025-06-23):&lt;/strong&gt; Recently, Luke Shaw added a &lt;a class="reference external" href="https://github.com/Blosc/python-blosc2/pull/427#pullrequestreview-2948922546"&gt;stack() function in Blosc2&lt;/a&gt;, using the concatenate feature described here. The new function allows you to stack arrays along a new axis, which is particularly useful for creating higher-dimensional arrays from lower-dimensional ones.  We have added a section at the end of this post to show the usage and performance of this new function.&lt;/p&gt;
&lt;p&gt;---&lt;/p&gt;
&lt;p&gt;Blosc2 just got a cool new trick: super-efficient array concatenation! If you've ever needed to combine several arrays into one, especially when dealing with lots of data, this new feature is for you. It's built to be fast and use as little memory as possible. This is especially true if your array sizes line up nicely with Blosc2's internal "chunks" (think of these as the building blocks of your compressed data). When this alignment happens, concatenation is lightning-fast, making it perfect for demanding tasks.&lt;/p&gt;
&lt;p&gt;You can use this new concatenate feature whether you're &lt;a class="reference external" href="https://www.blosc.org/c-blosc2/reference/b2nd.html#c.b2nd_concatenate"&gt;coding in C&lt;/a&gt; or &lt;a class="reference external" href="https://www.blosc.org/python-blosc2/reference/autofiles/ndarray/blosc2.concatenate.html"&gt;Python&lt;/a&gt;, and it works with any Blosc2 NDArray (Blosc2's way of handling multi-dimensional arrays).&lt;/p&gt;
&lt;p&gt;Let's see how easy it is to use in Python. If you're familiar with NumPy, the &lt;cite&gt;blosc2.concatenate&lt;/cite&gt; function will feel very similar:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code python"&gt;&lt;a id="rest_code_9576a4231d5944e68b238a83e5406435-1" name="rest_code_9576a4231d5944e68b238a83e5406435-1" href="https://blosc.org/posts/blosc2-new-concatenate/#rest_code_9576a4231d5944e68b238a83e5406435-1"&gt;&lt;/a&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;blosc2&lt;/span&gt;
&lt;a id="rest_code_9576a4231d5944e68b238a83e5406435-2" name="rest_code_9576a4231d5944e68b238a83e5406435-2" href="https://blosc.org/posts/blosc2-new-concatenate/#rest_code_9576a4231d5944e68b238a83e5406435-2"&gt;&lt;/a&gt;&lt;span class="c1"&gt;# Create some sample arrays&lt;/span&gt;
&lt;a id="rest_code_9576a4231d5944e68b238a83e5406435-3" name="rest_code_9576a4231d5944e68b238a83e5406435-3" href="https://blosc.org/posts/blosc2-new-concatenate/#rest_code_9576a4231d5944e68b238a83e5406435-3"&gt;&lt;/a&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;blosc2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;full&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;urlpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"arrayA.b2nd"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"w"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_9576a4231d5944e68b238a83e5406435-4" name="rest_code_9576a4231d5944e68b238a83e5406435-4" href="https://blosc.org/posts/blosc2-new-concatenate/#rest_code_9576a4231d5944e68b238a83e5406435-4"&gt;&lt;/a&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;blosc2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;full&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;urlpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"arrayB.b2nd"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"w"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_9576a4231d5944e68b238a83e5406435-5" name="rest_code_9576a4231d5944e68b238a83e5406435-5" href="https://blosc.org/posts/blosc2-new-concatenate/#rest_code_9576a4231d5944e68b238a83e5406435-5"&gt;&lt;/a&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;blosc2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;full&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;urlpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"arrayC.b2nd"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"w"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_9576a4231d5944e68b238a83e5406435-6" name="rest_code_9576a4231d5944e68b238a83e5406435-6" href="https://blosc.org/posts/blosc2-new-concatenate/#rest_code_9576a4231d5944e68b238a83e5406435-6"&gt;&lt;/a&gt;&lt;span class="c1"&gt;# Concatenate the arrays along the first axis&lt;/span&gt;
&lt;a id="rest_code_9576a4231d5944e68b238a83e5406435-7" name="rest_code_9576a4231d5944e68b238a83e5406435-7" href="https://blosc.org/posts/blosc2-new-concatenate/#rest_code_9576a4231d5944e68b238a83e5406435-7"&gt;&lt;/a&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;blosc2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;axis&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;urlpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"destination.b2nd"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"w"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_9576a4231d5944e68b238a83e5406435-8" name="rest_code_9576a4231d5944e68b238a83e5406435-8" href="https://blosc.org/posts/blosc2-new-concatenate/#rest_code_9576a4231d5944e68b238a83e5406435-8"&gt;&lt;/a&gt;&lt;span class="c1"&gt;# The result is a new Blosc2 NDArray containing the concatenated data&lt;/span&gt;
&lt;a id="rest_code_9576a4231d5944e68b238a83e5406435-9" name="rest_code_9576a4231d5944e68b238a83e5406435-9" href="https://blosc.org/posts/blosc2-new-concatenate/#rest_code_9576a4231d5944e68b238a83e5406435-9"&gt;&lt;/a&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shape&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Output: (30, 20)&lt;/span&gt;
&lt;a id="rest_code_9576a4231d5944e68b238a83e5406435-10" name="rest_code_9576a4231d5944e68b238a83e5406435-10" href="https://blosc.org/posts/blosc2-new-concatenate/#rest_code_9576a4231d5944e68b238a83e5406435-10"&gt;&lt;/a&gt;&lt;span class="c1"&gt;# You can also concatenate along other axes&lt;/span&gt;
&lt;a id="rest_code_9576a4231d5944e68b238a83e5406435-11" name="rest_code_9576a4231d5944e68b238a83e5406435-11" href="https://blosc.org/posts/blosc2-new-concatenate/#rest_code_9576a4231d5944e68b238a83e5406435-11"&gt;&lt;/a&gt;&lt;span class="n"&gt;result_axis1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;blosc2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;axis&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;urlpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"destination_axis1.b2nd"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"w"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_9576a4231d5944e68b238a83e5406435-12" name="rest_code_9576a4231d5944e68b238a83e5406435-12" href="https://blosc.org/posts/blosc2-new-concatenate/#rest_code_9576a4231d5944e68b238a83e5406435-12"&gt;&lt;/a&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result_axis1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shape&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Output: (10, 60)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;cite&gt;blosc2.concatenate&lt;/cite&gt; function is pretty straightforward. You give it a list of the arrays you want to join together. You can also tell it which way to join them using the axis parameter (like joining them end-to-end or side-by-side).&lt;/p&gt;
&lt;p&gt;A really handy feature is that you can use urlpath and mode to save the combined array directly to a file. This is great when you're working with huge datasets because you don't have to load everything into memory at once. What you get back is a brand new, persistent Blosc2 NDArray with all your data combined.&lt;/p&gt;
&lt;section id="aligned-versus-non-aligned-concatenation"&gt;
&lt;h2&gt;Aligned versus Non-Aligned Concatenation&lt;/h2&gt;
&lt;p&gt;Blosc2's concatenate function is smart. It processes your data in small pieces of compressed data (chunks). This has two consequences. The first is that you can join very large arrays, stored on your disk, chunk-by-chunk without using up all your computer's memory. Secondly, if the chunks fit neatly into the arrays to be concatenated, the process is much faster. Why? Because Blosc2 can avoid a lot of extra work, chiefly decompressing and re-compressing the chunks.&lt;/p&gt;
&lt;p&gt;Let's look at some pictures to see what "aligned" and "unaligned" concatenation means. "Aligned" means that chunk boundaries of the arrays to be concatenated line up with each other. "Unaligned" means that this is not the case.&lt;/p&gt;
&lt;img alt="/images/blosc2-new-concatenate/concat-unaligned.png" src="https://blosc.org/images/blosc2-new-concatenate/concat-unaligned.png"&gt;
&lt;img alt="/images/blosc2-new-concatenate/concat-aligned.png" src="https://blosc.org/images/blosc2-new-concatenate/concat-aligned.png"&gt;
&lt;p&gt;The pictures show why "aligned" concatenation is faster. In Blosc2, all data pieces (chunks) inside an array must be the same size. So, if the chunks in the arrays you're joining match up ("aligned"), Blosc2 can combine them very quickly. It doesn't have to rearrange the data into new, same-sized chunks for the final array. This is a big deal for large arrays.&lt;/p&gt;
&lt;p&gt;If the arrays are "unaligned," Blosc2 has more work to do. It has to decompress and then re-compress the data to make the new chunks fit, which takes longer. There's one more small detail for this fast method to work: the first array's size needs to be a neat multiple of its chunk size along the direction you're joining.&lt;/p&gt;
&lt;p&gt;A big plus with Blosc2 is that it always processes data in these small chunks. This means it can combine enormous arrays without ever needing to load everything into your computer's memory at once.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance"&gt;
&lt;h2&gt;Performance&lt;/h2&gt;
&lt;p&gt;To show you how much faster this new concatenate feature is, we did a speed test using LZ4 as the internal compressor in Blosc2. We compared it to the usual way of joining arrays with &lt;cite&gt;numpy.concatenate&lt;/cite&gt;.&lt;/p&gt;
&lt;img alt="/images/blosc2-new-concatenate/benchmark-lz4-20k-i13900K.png" src="https://blosc.org/images/blosc2-new-concatenate/benchmark-lz4-20k-i13900K.png"&gt;
&lt;p&gt;The speed tests show that Blosc2's new concatenate is rather slow for small arrays (like 1,000 x 1,000). This is because it has to do a lot of work to set up the concatenation. But when you use larger arrays (like 20,000 x 20,000) that start to exceed the memory limits of our test machine (32 GB of RAM), Blosc2's new concatenate peformance is much better, and nearing the performance of NumPy's &lt;cite&gt;concatenate&lt;/cite&gt; function.&lt;/p&gt;
&lt;p&gt;However, if your array sizes line up well with Blosc2's internal chunks ("aligned" arrays), Blosc2 becomes much faster—typically more than 10x times faster than NumPy for large arrays. This is because it can skip a lot of the work of decompressing and re-compressing data, and the cost of copying compressed data is also lower (as much as the achieved compression ratio, which for this case is around 10x).&lt;/p&gt;
&lt;p&gt;Using the Zstd compressor with Blosc2 can make joining "aligned" arrays even quicker, since Zstd is good at making data smaller.&lt;/p&gt;
&lt;img alt="/images/blosc2-new-concatenate/benchmark-zstd-20k-i13900K.png" src="https://blosc.org/images/blosc2-new-concatenate/benchmark-zstd-20k-i13900K.png"&gt;
&lt;p&gt;So, when arrays are aligned, there's less data to copy (compression ratios here are around 20x), which speeds things up. If arrays aren't aligned, Zstd is a bit slower than the previous compressor (LZ4) because its decompression and re-compression algorithm is slower. Conclusion? Pick the compressor that works best for what you're doing!&lt;/p&gt;
&lt;/section&gt;
&lt;section id="stacking-arrays"&gt;
&lt;h2&gt;Stacking Arrays&lt;/h2&gt;
&lt;p&gt;We've also added a new &lt;cite&gt;stack()&lt;/cite&gt; function in Blosc2 that uses the concatenate feature. This function lets you stack arrays along a new axis, which is super useful for creating higher-dimensional arrays from lower-dimensional ones. Here's how it works:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code python"&gt;&lt;a id="rest_code_196245606a4f4cbd837c954f95d146d9-1" name="rest_code_196245606a4f4cbd837c954f95d146d9-1" href="https://blosc.org/posts/blosc2-new-concatenate/#rest_code_196245606a4f4cbd837c954f95d146d9-1"&gt;&lt;/a&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;blosc2&lt;/span&gt;
&lt;a id="rest_code_196245606a4f4cbd837c954f95d146d9-2" name="rest_code_196245606a4f4cbd837c954f95d146d9-2" href="https://blosc.org/posts/blosc2-new-concatenate/#rest_code_196245606a4f4cbd837c954f95d146d9-2"&gt;&lt;/a&gt;&lt;span class="c1"&gt;# Create some sample arrays&lt;/span&gt;
&lt;a id="rest_code_196245606a4f4cbd837c954f95d146d9-3" name="rest_code_196245606a4f4cbd837c954f95d146d9-3" href="https://blosc.org/posts/blosc2-new-concatenate/#rest_code_196245606a4f4cbd837c954f95d146d9-3"&gt;&lt;/a&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;blosc2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;full&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;urlpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"arrayA.b2nd"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"w"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_196245606a4f4cbd837c954f95d146d9-4" name="rest_code_196245606a4f4cbd837c954f95d146d9-4" href="https://blosc.org/posts/blosc2-new-concatenate/#rest_code_196245606a4f4cbd837c954f95d146d9-4"&gt;&lt;/a&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;blosc2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;full&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;urlpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"arrayB.b2nd"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"w"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_196245606a4f4cbd837c954f95d146d9-5" name="rest_code_196245606a4f4cbd837c954f95d146d9-5" href="https://blosc.org/posts/blosc2-new-concatenate/#rest_code_196245606a4f4cbd837c954f95d146d9-5"&gt;&lt;/a&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;blosc2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;full&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;urlpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"arrayC.b2nd"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"w"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_196245606a4f4cbd837c954f95d146d9-6" name="rest_code_196245606a4f4cbd837c954f95d146d9-6" href="https://blosc.org/posts/blosc2-new-concatenate/#rest_code_196245606a4f4cbd837c954f95d146d9-6"&gt;&lt;/a&gt;&lt;span class="c1"&gt;# Stack the arrays along a new axis&lt;/span&gt;
&lt;a id="rest_code_196245606a4f4cbd837c954f95d146d9-7" name="rest_code_196245606a4f4cbd837c954f95d146d9-7" href="https://blosc.org/posts/blosc2-new-concatenate/#rest_code_196245606a4f4cbd837c954f95d146d9-7"&gt;&lt;/a&gt;&lt;span class="n"&gt;stacked_result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;blosc2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;axis&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;urlpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"stacked_destination.b2nd"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"w"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_196245606a4f4cbd837c954f95d146d9-8" name="rest_code_196245606a4f4cbd837c954f95d146d9-8" href="https://blosc.org/posts/blosc2-new-concatenate/#rest_code_196245606a4f4cbd837c954f95d146d9-8"&gt;&lt;/a&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stacked_result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shape&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Output: (3, 10, 20)&lt;/span&gt;
&lt;a id="rest_code_196245606a4f4cbd837c954f95d146d9-9" name="rest_code_196245606a4f4cbd837c954f95d146d9-9" href="https://blosc.org/posts/blosc2-new-concatenate/#rest_code_196245606a4f4cbd837c954f95d146d9-9"&gt;&lt;/a&gt;&lt;span class="c1"&gt;# You can also stack along other axes&lt;/span&gt;
&lt;a id="rest_code_196245606a4f4cbd837c954f95d146d9-10" name="rest_code_196245606a4f4cbd837c954f95d146d9-10" href="https://blosc.org/posts/blosc2-new-concatenate/#rest_code_196245606a4f4cbd837c954f95d146d9-10"&gt;&lt;/a&gt;&lt;span class="n"&gt;stacked_result_axis1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;blosc2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;axis&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;urlpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"stacked_destination_axis1.b2nd"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"w"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_196245606a4f4cbd837c954f95d146d9-11" name="rest_code_196245606a4f4cbd837c954f95d146d9-11" href="https://blosc.org/posts/blosc2-new-concatenate/#rest_code_196245606a4f4cbd837c954f95d146d9-11"&gt;&lt;/a&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stacked_result_axis1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shape&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Output: (10, 3, 20)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Benchmarks for the &lt;cite&gt;stack()&lt;/cite&gt; function show that it performs similarly to the &lt;cite&gt;concat()&lt;/cite&gt; function, especially when the input arrays are aligned.  Here are the results for the same data sizes and machine used in the previous benchmarks, and using the LZ4 compressor.&lt;/p&gt;
&lt;img alt="/images/blosc2-new-concatenate/stack-lz4-20k-i13900K.png" src="https://blosc.org/images/blosc2-new-concatenate/stack-lz4-20k-i13900K.png"&gt;
&lt;p&gt;And here are the results for the Zstd compressor.&lt;/p&gt;
&lt;img alt="/images/blosc2-new-concatenate/stack-zstd-20k-i13900K.png" src="https://blosc.org/images/blosc2-new-concatenate/stack-zstd-20k-i13900K.png"&gt;
&lt;p&gt;As can be seen, the &lt;cite&gt;stack()&lt;/cite&gt; function is also very fast when the input arrays are aligned, and it performs well even for large arrays that don't fit into memory. Incidentally, when using the &lt;cite&gt;blosc2.stack()&lt;/cite&gt; function in the last dim, it is slightly faster than &lt;cite&gt;numpy.stack()&lt;/cite&gt; even when the arrays are not aligned; we are not sure why this is the case, but the fact that we can reproduces this behaviour is probably a sign that NumPy can optimize this use case better.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="conclusion"&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Blosc2's new concatenate and stack features are a great way to combine arrays quickly and without using too much memory. They are especially fast when your array sizes are an exact multiple of Blosc2's "chunks" (aligned arrays), making it perfect for big data jobs. They also work well for large arrays that don't fit into memory, as it processes data in small chunks. Finally, they are supported in both C and Python, so you can use them in your favorite programming language.&lt;/p&gt;
&lt;p&gt;Give it a try in your own projects! If you have questions, the Blosc2 community is here to help.&lt;/p&gt;
&lt;p&gt;If you appreciate what we're doing with Blosc2, please think about &lt;a class="reference external" href="https://www.blosc.org/pages/blosc-in-depth/#support-blosc/"&gt;supporting us&lt;/a&gt;. Your help lets us keep making these tools better.&lt;/p&gt;
&lt;/section&gt;</description><category>blosc2 concatenate performance</category><guid>https://blosc.org/posts/blosc2-new-concatenate/</guid><pubDate>Mon, 16 Jun 2025 13:33:20 GMT</pubDate></item></channel></rss>