Skip to content

Commit 6189b07

Browse files
committed
FIX: displaying Polars *Frame when pyarrow is not installed (fixes #324)
1 parent 5fc7814 commit 6189b07

2 files changed

Lines changed: 25 additions & 13 deletions

File tree

‎doc/source/changes/version_0_35_2.rst.inc‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,7 @@ Fixes
4646
Closes :editor_issue:`327`).
4747

4848
* fixed displaying Pandas 3+ DataFrame and Series when pyarrow is not installed
49-
(closes :editor_issue:`322`).
49+
(closes :editor_issue:`322`).
50+
51+
* fixed displaying Polars *Frame when pyarrow is not installed
52+
(closes :editor_issue:`324`).

‎larray_editor/arrayadapter.py‎

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2314,6 +2314,22 @@ def get_values(self, h_start, v_start, h_stop, v_stop):
23142314
return np.stack(np_columns, axis=1, dtype=object)
23152315

23162316

2317+
def _polars_frame_to_2d_seq(chunk):
2318+
# We do not go via Pandas, which is a tad easier because it requires both
2319+
# Pandas and pyarrow installed
2320+
dtypes = chunk.dtypes
2321+
dt0 = dtypes[0]
2322+
homogeneous_dtypes = all(dt == dt0 for dt in dtypes[1:])
2323+
if homogeneous_dtypes:
2324+
return chunk.to_numpy()
2325+
else:
2326+
# For mixed dtypes, we go via a structured array to avoid casting
2327+
# everything to a single type (e.g. datetime column to float)
2328+
struct_arr = chunk.to_numpy(structured=True)
2329+
assert struct_arr.ndim == 1
2330+
return [list(row_data) for row_data in struct_arr]
2331+
2332+
23172333
@adapter_for('polars.DataFrame')
23182334
@adapter_for('narwhals.DataFrame')
23192335
class PolarsDataFrameAdapter(AbstractColumnarAdapter):
@@ -2330,11 +2346,8 @@ def get_hlabels_values(self, start, stop):
23302346
return [self.sorted_data.columns[start:stop]]
23312347

23322348
def get_values(self, h_start, v_start, h_stop, v_stop):
2333-
# Going via Pandas instead of directly using to_numpy() because this
2334-
# has a better behavior for datetime columns (e.g. pl_df3).
2335-
# Otherwise, Polars converts datetimes to floats instead using a numpy
2336-
# object array
2337-
return self.sorted_data[v_start:v_stop, h_start:h_stop].to_pandas().values
2349+
chunk = self.sorted_data[v_start:v_stop, h_start:h_stop]
2350+
return _polars_frame_to_2d_seq(chunk)
23382351

23392352
def can_sort_hlabel(self, row_idx, col_idx):
23402353
return True
@@ -2425,13 +2438,9 @@ def get_hlabels_values(self, start, stop):
24252438
def get_values(self, h_start, v_start, h_stop, v_stop):
24262439
lf = self.sorted_data
24272440
row_subset = lf[v_start:v_stop]
2428-
subset = row_subset.select(self._columns[h_start:h_stop])
2429-
df = subset.collect(engine='streaming')
2430-
# Going via Pandas instead of directly using to_numpy() because this
2431-
# has a better behavior for datetime columns (e.g. pl_df3).
2432-
# Otherwise, Polars converts datetimes to floats instead using a numpy
2433-
# object array
2434-
return df.to_pandas().values
2441+
subset_query = row_subset.select(self._columns[h_start:h_stop])
2442+
chunk = subset_query.collect(engine='streaming')
2443+
return _polars_frame_to_2d_seq(chunk)
24352444

24362445
def can_sort_hlabel(self, row_idx, col_idx):
24372446
return True

0 commit comments

Comments
 (0)