<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Improvements to PyArrow for Astronomy | GSoC'26 - OpenAstronomy]]></title><description><![CDATA[Improvements to PyArrow for Astronomy | GSoC'26 - OpenAstronomy]]></description><link>https://imporving-pyarrow-for-nested-structures.hashnode.dev</link><image><url>https://cdn.hashnode.com/uploads/logos/69cbd2f4c1e86567d73c63eb/3443afe6-3f51-42df-9cf3-a4bc8fdac613.svg</url><title>Improvements to PyArrow for Astronomy | GSoC&apos;26 - OpenAstronomy</title><link>https://imporving-pyarrow-for-nested-structures.hashnode.dev</link></image><generator>RSS for Node</generator><lastBuildDate>Wed, 24 Jun 2026 12:31:24 GMT</lastBuildDate><atom:link href="https://imporving-pyarrow-for-nested-structures.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Results are out!!!]]></title><description><![CDATA[My GSoC project's main goals includes parallelizing the reading of structs in parquet files. This is very beneficial to the community as astronomical data involves data stored in structs and other nes]]></description><link>https://imporving-pyarrow-for-nested-structures.hashnode.dev/results-are-out</link><guid isPermaLink="true">https://imporving-pyarrow-for-nested-structures.hashnode.dev/results-are-out</guid><dc:creator><![CDATA[Om Biradar]]></dc:creator><pubDate>Sun, 14 Jun 2026 12:08:19 GMT</pubDate><content:encoded><![CDATA[<p>My GSoC project's main goals includes parallelizing the reading of structs in parquet files. This is very beneficial to the community as astronomical data involves data stored in structs and other nested structures.</p>
<img src="https://cdn.hashnode.com/uploads/covers/69cbd2f4c1e86567d73c63eb/79712cfd-bfff-44aa-b909-7dd5cb572175.png" alt="" style="display:block;margin:0 auto" />

<p>This figure shows the performance increase/decrease the optimized parquet reader (which I made) has over the baseline main branch of apache/arrow when run on a standard free GitHub runner and the file in loaded into the RAM to remove the I/O overhead which is not relevant here.</p>
<p>For smaller files, the overhead of multi threading causes it to be slower, but for real life cases when the file sizes are large, the optimized reader now provides 25%-30%+ faster reading times.</p>
<img src="https://cdn.hashnode.com/uploads/covers/69cbd2f4c1e86567d73c63eb/8f49160a-b4ca-43a5-810f-b5bfa82d9766.png" alt="" style="display:block;margin:0 auto" />

<p>When compared to flat parquet files, the nested struct now offer similar read speeds with multi threading enabled!!</p>
<p>Overally, the project is going at a great pace with verifiable results. I hope this integrates with the upstream apache arrow library soon so that this performance boost can help the people working with PyArrow on astronomy datasets.</p>
<p>The link to the PR - <a href="https://github.com/apache/arrow/pull/50158">https://github.com/apache/arrow/pull/50158</a></p>
<p>Link to the results colab notebook - <a href="https://colab.research.google.com/drive/1TsxFkBSI_Iq0hfXEwNDs_D24acr3yxdC?usp=sharing">https://colab.research.google.com/drive/1TsxFkBSI_Iq0hfXEwNDs_D24acr3yxdC?usp=sharing</a></p>
<p>Orchestrating and benchmarking repo - <a href="https://github.com/OmBiradar/pyarrow-lincc-fw-openastronomy-gsoc26">https://github.com/OmBiradar/pyarrow-lincc-fw-openastronomy-gsoc26</a></p>
]]></content:encoded></item><item><title><![CDATA[Community Bonding and week 1 & 2]]></title><description><![CDATA[The start was amazing! The community bonding was really great. I got to meet the mentors, get to know the whole organization structure of OpenAstronomy and LINCC frameworks, the work they do, the peop]]></description><link>https://imporving-pyarrow-for-nested-structures.hashnode.dev/community-bonding-and-week-1-2</link><guid isPermaLink="true">https://imporving-pyarrow-for-nested-structures.hashnode.dev/community-bonding-and-week-1-2</guid><dc:creator><![CDATA[Om Biradar]]></dc:creator><pubDate>Tue, 09 Jun 2026 03:27:42 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/69cbd2f4c1e86567d73c63eb/ee778394-fab9-4312-9091-8f68196be4a5.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The start was amazing! The community bonding was really great. I got to meet the mentors, get to know the whole organization structure of OpenAstronomy and LINCC frameworks, the work they do, the people and facilities associated with it, the ways PyArrow and nested-pandas was being used in astronomy and the expectations they had form the internship. They offered to help me through tasks if I could not do it on my own along with some content to look through to get a deeper understanding of the project. I attended the Apache Arrow community meeting with my mentor to introduce the project them and get their views on it. They were really helpful and even suggested certain thing to do to improve the final PR.</p>
<p>Week 1 and 2 were spent on improving the parallel reading of parquet files, which was successfully implemented by me. The benchmarking of these performance changes proved quite hard, as this would require the following, starting with the main arrow branch:</p>
<ol>
<li><p>Building arrow C++ from source</p>
</li>
<li><p>Building PyArrow from source</p>
</li>
<li><p>Running benchmarking scripts</p>
</li>
<li><p>Switching the branch from the main branch and repeating steps 1-3</p>
</li>
</ol>
<p>The time taken to benchmark the changes for all order of magnitude of files proved to be very long, approximately ~140 hours or 6 days. I could speed this up using parallel jobs in github which needed to be configured separately using config settings and matrix github runners. This needed to be done because github sets a timeout of 6 hours on each github action with at max 20 concurrent jobs and a 24 hour auto cancel timeout on jobs in queue. Based on these constraints I had to figure out a way to orchestrate different runners and combine their results for which I used sqlite3.</p>
]]></content:encoded></item><item><title><![CDATA[Proposal for Improving PyArrow for Astronomy]]></title><description><![CDATA[Motivation
I was casually interviewing at a HFT, answering questions about C++ and systems, when the interviewer questioned if I ever used arrow in C++ for data processing/handling. I having only used]]></description><link>https://imporving-pyarrow-for-nested-structures.hashnode.dev/proposal-for-improving-pyarrow-for-astronomy</link><guid isPermaLink="true">https://imporving-pyarrow-for-nested-structures.hashnode.dev/proposal-for-improving-pyarrow-for-astronomy</guid><dc:creator><![CDATA[Om Biradar]]></dc:creator><pubDate>Tue, 31 Mar 2026 17:41:51 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/69cbd2f4c1e86567d73c63eb/40e610b8-8f8d-4d0b-a571-7805300b9945.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h4>Motivation</h4>
<p>I was casually interviewing at a HFT, answering questions about C++ and systems, when the interviewer questioned if I ever used <code>arrow</code> in C++ for data processing/handling. I having only used <code>enigma</code>, didn't ever use <code>arrow</code> at that time. This made me curious about it. On a side note, I did eventually did get placed at a similar role.</p>
<p>I saw that <code>arrow</code> was coming up as a project in GSoC 2026 which peaked by interest - along with that I saw it's under <code>OpenAstronomy</code>. I was like "WOW!", it's kind of like a childhood dream come true of working like an Astronomer. Not exactly an astronomer I know, but quite close to it as to support the community.</p>
<h4>Technical breakdown of proposal</h4>
<p>Thus, I decided to apply for GSoC 2026 for the "Improvements to <code>PyArrow</code> for Astronomy" project. This project majorly deals with improving the support for nested type structures in parquet files and the processing of these in <code>arrow</code> / <code>PyArrow</code>. In some more depth, the issues are -</p>
<ol>
<li><p><strong>Parquet file doesn't utilize parallel processing in structs</strong>: This causes structs to not be read as fast as possible with multi-threading even tho it's actually possible and completely safe to do so. Using multi-threading here would enable the reading of many datasets in astronomy like the light curves data very fast. Also it's evident that this would help in general data processing of any sort. The root cause is that <code>StructReader::LoadBatch()</code> and <code>StructReader::BuildArray()</code> currently iterate over child fields serially. However, since each child manages its own <code>RecordReader</code>, <code>PageReader</code>, and output buffers with no shared mutable state (no race conditions), parallel execution is completely thread-safe. By leveraging the existing <code>OptionalParallelFor</code> multi-threading support within the arrow project, we can parallely processing each child of a struct using the CPU thread pool when <code>set_use_threads</code>(true) is enabled. This particularly speeds up processing for time-series astronomy data (like light curves, spectral arrays) where structs may contain large numeric child fields. This implementation would have no change in the API and is purely a performance improvement. Appropriate benchmarks to performance test this change will also be written by me.</p>
</li>
<li><p><strong>Cannot select child columns inside LIST-STRUCT types</strong>: If we wanted to select <code>A.b</code> where <code>A</code> is of type <code>list&lt;struct&lt;b: int, c: int&gt;&gt;</code> and <code>b</code> is a field/child of the struct <code>A</code>, currently <code>PyArrow</code> doesn't support this. Where as selecting child columns from regular struct types (like selecting <code>P.a</code> where <code>P</code> is a struct) is currently supported. The issue arises specifically when the STRUCT is nested inside a LIST. My proposal is to expand the nested field resolution logic to detect when a field is a LIST or LARGE_LIST type, unwrap it to access the list's element type, and then search for child fields within that element (which may be a STRUCT type). This would successfully allow selection of type <code>A.b</code> where A is of the type <code>list&lt;struct&lt;b: int, c: int&gt;&gt;</code>.</p>
</li>
<li><p><strong>Arrow compute kernels lack functionality for nested data</strong>: the kernels like <code>replace_with_mask</code> do not currently support data types like lists and lists of structs or any such nested data types. Thus this would need to be added for it to support of nested types. The main problem is that supporting nested types means supporting the infinite combinations of nested types of data that are possible like <code>&lt;list&lt;list&lt;struct&gt;&gt;&gt;</code> or <code>&lt;list&lt;struct&gt;&gt;</code> and infinite more. Thus the support for these datatypes in the kernels must be added dynamically. There is another problem - if we figure out how to handle each nested data by looking at the schema this might be bit inefficient than using a onion peel method - first we unpack the top data structure, consider example as <code>&lt;list&lt;struct&gt;&gt;</code> we unpack <code>list</code> first using a method that knows how to unpack <code>lsit</code>. Then we pass it to a method that further tries to unpack the data. Here we are left with <code>struct</code>. Thus a function that knows how to unpack <code>struct</code> works on it and unpacks it. Thus now we are left with non-nested data types that the existing methods will handle. This is my proposal - to use this smart technique to handle nested data layer by layer dynamically.</p>
</li>
</ol>
]]></content:encoded></item></channel></rss>