<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Arrow on Asadbek Kurbonov</title><link>/tags/arrow/</link><description>Recent content in Arrow on Asadbek Kurbonov</description><generator>Hugo</generator><language>en</language><lastBuildDate>Sun, 20 Sep 2026 19:45:00 +0200</lastBuildDate><atom:link href="/tags/arrow/index.xml" rel="self" type="application/rss+xml"/><item><title>ursus: A Dataframe Library for Go, and What It Is Honestly Worth</title><link>/posts/ursus-dataframes-in-go/</link><pubDate>Sun, 20 Sep 2026 19:45:00 +0200</pubDate><guid>/posts/ursus-dataframes-in-go/</guid><description>&lt;p>I have spent the last weeks building &lt;a href="https://github.com/advenn/ursus">ursus&lt;/a> — a dataframe library for Go modelled
on Polars. Lazy execution with a query optimizer, Arrow memory layout, SIMD kernels, and streaming execution that spills
to disk instead of falling over.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">df&lt;/span>, &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">ursus&lt;/span>.&lt;span style="color:#a6e22e">ScanParquet&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;events.parquet&amp;#34;&lt;/span>).
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Filter&lt;/span>(&lt;span style="color:#a6e22e">ursus&lt;/span>.&lt;span style="color:#a6e22e">Col&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;price&amp;#34;&lt;/span>).&lt;span style="color:#a6e22e">Gt&lt;/span>(&lt;span style="color:#ae81ff">5&lt;/span>)).
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">GroupBy&lt;/span>(&lt;span style="color:#a6e22e">ursus&lt;/span>.&lt;span style="color:#a6e22e">Col&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;region&amp;#34;&lt;/span>)).
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Agg&lt;/span>(
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">ursus&lt;/span>.&lt;span style="color:#a6e22e">Col&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;price&amp;#34;&lt;/span>).&lt;span style="color:#a6e22e">Sum&lt;/span>().&lt;span style="color:#a6e22e">Alias&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;revenue&amp;#34;&lt;/span>),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">ursus&lt;/span>.&lt;span style="color:#a6e22e">Col&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;qty&amp;#34;&lt;/span>).&lt;span style="color:#a6e22e">Mean&lt;/span>().&lt;span style="color:#a6e22e">Alias&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;avg_qty&amp;#34;&lt;/span>),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ).
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Sort&lt;/span>(&lt;span style="color:#a6e22e">ursus&lt;/span>.&lt;span style="color:#a6e22e">Desc&lt;/span>(&lt;span style="color:#a6e22e">ursus&lt;/span>.&lt;span style="color:#a6e22e">Col&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;revenue&amp;#34;&lt;/span>))).
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Collect&lt;/span>(&lt;span style="color:#a6e22e">ctx&lt;/span>)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The projection reaches the Parquet reader, the filter becomes a row-group predicate, and the group-by runs on every
core. None of that shows up in the query.&lt;/p></description></item></channel></rss>