@@ -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' )
23192335class 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