[Data] Avoid per-column Series materialization in tensor-column casting - #64038
Conversation
…andas conversion between numpy and tensors Signed-off-by: Ayush Kumar <ayushk7102@gmail.com>
There was a problem hiding this comment.
Code Review
This pull request optimizes pandas DataFrame conversions by scanning df.dtypes instead of df.items(), avoiding the unnecessary materialization of Series objects for non-tensor columns. The reviewer identified a critical issue where duplicate column names in the DataFrame would cause df[col_name] to return a DataFrame instead of a Series, leading to runtime errors. To resolve this, the reviewer suggested iterating with enumerate(df.dtypes.items()) and retrieving columns safely by index using df.iloc[:, i].
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
|
@goutamvenkat-anyscale A few comments to address conversion overhead: Note that we cannot This is different from the |
…e columns case (regression) Signed-off-by: Ayush Kumar <ayushk7102@gmail.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
Reviewed by Cursor Bugbot for commit b71c050. Configure here.
Signed-off-by: Ayush Kumar <ayushk7102@gmail.com>
…ng (ray-project#64038) ## Description When we are converting tensor columns of a block/batch to ndarrays and vice versa, our current implementation scans over the columns using `df.items()` and checks the dtype of each column. This is wasteful as we pay the cost of materializing the column as a `pd.Series` just to check its dtype. Instead, what we can do is iterate over the `df.dtypes.items()` which only yields numpy dtype objects. `_cast_tensor_columns_to_ndarrays` and `_cast_ndarray_columns_to_tensor_extension` in `data_batch_conversion.py` `.items()`. `df.items()` materializes a pandas `Series` for every column just so the body can read its dtype: which is wasteful when most (or all) columns aren't tensor columns ## Additional Information ### Code paths | function | hot path | frequency | |---|---|---| | `_cast_tensor_columns_to_ndarrays` | `ArrowBlockAccessor.to_pandas()` | **per batch** in `iter_batches(pandas)` | | `_cast_ndarray_columns_to_tensor_extension` | `TableBlockBuilder.build()` → `_combine_tables()` | **per block built** | ### TODO: Add the microbenchmark --------- Signed-off-by: Ayush Kumar <ayushk7102@gmail.com>

Description
When we are converting tensor columns of a block/batch to ndarrays and vice versa, our current implementation scans over the columns using
df.items()and checks the dtype of each column. This is wasteful as we pay the cost of materializing the column as apd.Seriesjust to check its dtype. Instead, what we can do is iterate over thedf.dtypes.items()which only yields numpy dtype objects._cast_tensor_columns_to_ndarraysand_cast_ndarray_columns_to_tensor_extensionindata_batch_conversion.py.items().df.items()materializes a pandasSeriesfor every column just so the body can read its dtype: which is wasteful when most (or all) columns aren't tensor columnsAdditional Information
Code paths
_cast_tensor_columns_to_ndarraysArrowBlockAccessor.to_pandas()iter_batches(pandas)_cast_ndarray_columns_to_tensor_extensionTableBlockBuilder.build()→_combine_tables()TODO: Add the microbenchmark