diff --git a/py-polars/polars/dataframe/frame.py b/py-polars/polars/dataframe/frame.py index 827ddc9d8890..3bca63c971ea 100644 --- a/py-polars/polars/dataframe/frame.py +++ b/py-polars/polars/dataframe/frame.py @@ -1518,9 +1518,7 @@ def to_numpy( Fortran-like. In general, using the Fortran-like index order is faster. However, the C-like order might be more appropriate to use for downstream applications to prevent cloning data, e.g. when reshaping into a - one-dimensional array. Note that this option only takes effect if - `structured` is set to `False` and the DataFrame dtypes allow a - global dtype for all columns. + one-dimensional array. allow_copy Allow memory to be copied to perform the conversion. If set to `False`, causes conversions that are not zero-copy to fail. diff --git a/py-polars/src/interop/numpy/to_numpy_df.rs b/py-polars/src/interop/numpy/to_numpy_df.rs index c58870a9a6f2..9d14f230d2e3 100644 --- a/py-polars/src/interop/numpy/to_numpy_df.rs +++ b/py-polars/src/interop/numpy/to_numpy_df.rs @@ -145,7 +145,7 @@ fn df_to_numpy_with_copy( if let Some(arr) = try_df_to_numpy_numeric_supertype(py, df, order) { Ok(arr) } else { - df_columns_to_numpy(py, df, writable) + df_columns_to_numpy(py, df, order, writable) } } fn try_df_to_numpy_numeric_supertype( @@ -163,7 +163,12 @@ fn try_df_to_numpy_numeric_supertype( }; Some(np_array) } -fn df_columns_to_numpy(py: Python, df: &DataFrame, writable: bool) -> PyResult { +fn df_columns_to_numpy( + py: Python, + df: &DataFrame, + order: IndexOrder, + writable: bool, +) -> PyResult { let np_arrays = df.iter().map(|s| { let mut arr = series_to_numpy(py, s, writable, true).unwrap(); @@ -184,10 +189,17 @@ fn df_columns_to_numpy(py: Python, df: &DataFrame, writable: bool) -> PyResult

numpy + .getattr(intern!(py, "column_stack")) + .unwrap() + .call1((PyList::new_bound(py, np_arrays),))?, + IndexOrder::Fortran => numpy + .getattr(intern!(py, "vstack")) + .unwrap() + .call1((PyList::new_bound(py, np_arrays),))? + .getattr(intern!(py, "T"))?, + }; + + Ok(np_array.into()) } diff --git a/py-polars/tests/unit/interop/numpy/test_to_numpy_df.py b/py-polars/tests/unit/interop/numpy/test_to_numpy_df.py index 8c9579e973e7..0877c5852b02 100644 --- a/py-polars/tests/unit/interop/numpy/test_to_numpy_df.py +++ b/py-polars/tests/unit/interop/numpy/test_to_numpy_df.py @@ -220,13 +220,18 @@ def test_df_to_numpy_stacking_array() -> None: assert_array_equal(result[0][0], expected[0][0]) -def test_df_to_numpy_stacking_string() -> None: +@pytest.mark.parametrize("order", ["c", "fortran"]) +def test_df_to_numpy_stacking_string(order: IndexOrder) -> None: df = pl.DataFrame({"a": [1, 2, 3], "b": ["x", "y", "z"]}) - result = df.to_numpy() + result = df.to_numpy(order=order) expected = np.array([[1, "x"], [2, "y"], [3, "z"]], dtype=np.object_) assert_array_equal(result, expected) + if order == "c": + assert result.flags.c_contiguous is True + else: + assert result.flags.f_contiguous is True def test_to_numpy_chunked_16375() -> None: