The first step would be to check if your task can be solved natively using Polars Expressions.

If a custom function is neccessary, .map_elements() can be used to apply one on a row by row basis.

To pass in values from multiple columns, you can utilize the Struct data type.

e.g. with pl.struct()

Copy>>> df.select(pl.struct(pl.all())) # all columns
shape: (3, 1)
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ foo       β”‚
β”‚ ---       β”‚
β”‚ struct[3] β”‚
β•žβ•β•β•β•β•β•β•β•β•β•β•β•‘
β”‚ {1,4,7}   β”‚
β”‚ {2,5,8}   β”‚
β”‚ {3,6,9}   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Using pl.struct(...).map_elements will pass the values to the custom function as a dict argument.

Copydef my_complicated_function(row: dict) -> int:
    """
    A function that cannot utilize polars expressions.
    This should be avoided.
    """

    # a dict with column names as keys
    print(f"[DEBUG]: {row=}")
    
    # do some work
    return row["foo"] + row["bar"] + row["baz"]


df = pl.DataFrame({
    "foo": [1, 2, 3], 
    "bar": [4, 5, 6], 
    "baz": [7, 8, 9]
})

df = df.with_columns(
    pl.struct(pl.all())
      .map_elements(my_complicated_function, return_dtype=pl.Int64)
      .alias("foo + bar + baz")
)
Copy# [DEBUG]: row={'foo': 1, 'bar': 4, 'baz': 7}
# [DEBUG]: row={'foo': 2, 'bar': 5, 'baz': 8}
# [DEBUG]: row={'foo': 3, 'bar': 6, 'baz': 9}
Copyshape: (3, 4)
β”Œβ”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ foo ┆ bar ┆ baz ┆ foo + bar + baz β”‚
β”‚ --- ┆ --- ┆ --- ┆ ---             β”‚
β”‚ i64 ┆ i64 ┆ i64 ┆ i64             β”‚
β•žβ•β•β•β•β•β•ͺ═════β•ͺ═════β•ͺ═════════════════║
β”‚ 1   ┆ 4   ┆ 7   ┆ 12              β”‚
β”‚ 2   ┆ 5   ┆ 8   ┆ 15              β”‚
β”‚ 3   ┆ 6   ┆ 9   ┆ 18              β”‚
β””β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Answer from ritchie46 on Stack Overflow
Top answer
1 of 1
28

The first step would be to check if your task can be solved natively using Polars Expressions.

If a custom function is neccessary, .map_elements() can be used to apply one on a row by row basis.

To pass in values from multiple columns, you can utilize the Struct data type.

e.g. with pl.struct()

Copy>>> df.select(pl.struct(pl.all())) # all columns
shape: (3, 1)
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ foo       β”‚
β”‚ ---       β”‚
β”‚ struct[3] β”‚
β•žβ•β•β•β•β•β•β•β•β•β•β•β•‘
β”‚ {1,4,7}   β”‚
β”‚ {2,5,8}   β”‚
β”‚ {3,6,9}   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Using pl.struct(...).map_elements will pass the values to the custom function as a dict argument.

Copydef my_complicated_function(row: dict) -> int:
    """
    A function that cannot utilize polars expressions.
    This should be avoided.
    """

    # a dict with column names as keys
    print(f"[DEBUG]: {row=}")
    
    # do some work
    return row["foo"] + row["bar"] + row["baz"]


df = pl.DataFrame({
    "foo": [1, 2, 3], 
    "bar": [4, 5, 6], 
    "baz": [7, 8, 9]
})

df = df.with_columns(
    pl.struct(pl.all())
      .map_elements(my_complicated_function, return_dtype=pl.Int64)
      .alias("foo + bar + baz")
)
Copy# [DEBUG]: row={'foo': 1, 'bar': 4, 'baz': 7}
# [DEBUG]: row={'foo': 2, 'bar': 5, 'baz': 8}
# [DEBUG]: row={'foo': 3, 'bar': 6, 'baz': 9}
Copyshape: (3, 4)
β”Œβ”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ foo ┆ bar ┆ baz ┆ foo + bar + baz β”‚
β”‚ --- ┆ --- ┆ --- ┆ ---             β”‚
β”‚ i64 ┆ i64 ┆ i64 ┆ i64             β”‚
β•žβ•β•β•β•β•β•ͺ═════β•ͺ═════β•ͺ═════════════════║
β”‚ 1   ┆ 4   ┆ 7   ┆ 12              β”‚
β”‚ 2   ┆ 5   ┆ 8   ┆ 15              β”‚
β”‚ 3   ┆ 6   ┆ 9   ┆ 18              β”‚
β””β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
🌐
GeeksforGeeks
geeksforgeeks.org β€Ί python β€Ί how-to-apply-a-custom-function-in-polars-that-does-the-processing-row-by-row
How to Apply a Custom Function in Polars that Does the Processing Row by Row? - GeeksforGeeks
July 29, 2024 - In Polars, you can apply a custom function to each row using the apply method. The custom function can be defined to process data as needed.
Discussions

python - Apply function to all columns of a Polars-DataFrame - Stack Overflow
I know how to apply a function to all columns present in a Pandas-DataFrame. However, I have not figured out yet how to achieve this when using a Polars-DataFrame. I checked the section from the Po... More on stackoverflow.com
🌐 stackoverflow.com
Make it easy to apply a user-defined function to a DataFrame in Rust
Describe your feature request Both pandas DataFrame and Spark DataFrame support applying a user-defined function which take a row or multiple scalar values as input. Can we support the same in pola... More on github.com
🌐 github.com
11
May 24, 2022
Is there a "correct" way to convert a Pandas Function to Polars?
You can find a list of community-submitted learning resources here: https://dataengineering.wiki/Learning+Resources I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns. More on reddit.com
🌐 r/dataengineering
13
8
May 22, 2024
In polars, how to apply a custon function to a column of strings?
Hi, After looking at polars documentation, I'm having a really hard time to apply a custom function (taking a string, doing operations not available in polars and returning a new string) and get the result as a Vect. There is the possibility of UDF but it looks quite heavy to code. More on users.rust-lang.org
🌐 users.rust-lang.org
1
0
March 21, 2024
🌐
Towards Data Science
towardsdatascience.com β€Ί home β€Ί latest β€Ί manipulating values in polars dataframes
Manipulating Values in Polars DataFrames | Towards Data Science
January 29, 2025 - This means that the apply() function, when applied to a dataframe, sends the values of each row as a tuple to the receiving function. This is useful for some use cases.
🌐
Polars
docs.pola.rs β€Ί docs β€Ί python β€Ί version β€Ί 0.18 β€Ί reference β€Ί dataframe β€Ί api β€Ί polars.DataFrame.apply.html
polars.DataFrame.apply β€” Polars documentation
The UDF will receive each row as a tuple of values: udf(row). Implementing logic using a Python function is almost always _significantly_ slower and more memory intensive than implementing the same logic using the native expression API because: The native expression engine runs in Rust; UDFs run in Python. Use of Python UDFs forces the DataFrame to be materialized in memory. Polars-native expressions can be parallelised (UDFs typically cannot).
🌐
Polars
docs.pola.rs β€Ί user-guide β€Ί expressions β€Ί user-defined-python-functions
User-defined Python functions - Polars user guide
Still, you may need to pass an expression's state to a third party library or apply your black box function to data in Polars. In this part of the documentation we'll be using two APIs that allows you to do this: map_elements: Call a function separately on each value in the Series.
🌐
Polars
docs.pola.rs β€Ί py-polars β€Ί html β€Ί reference β€Ί expressions β€Ί functions.html
Functions β€” Polars documentation
These functions are available from the Polars module root and can be used as expressions, and sometimes also in eager contexts.
Find elsewhere
🌐
Polars
docs.pola.rs β€Ί api β€Ί python β€Ί version β€Ί 0.18 β€Ί reference β€Ί expressions β€Ί api β€Ί polars.apply.html
polars.apply β€” Polars documentation
Apply a custom/user-defined function (UDF) in a GroupBy context Β· This method is much slower than the native expressions API. Only use it if you cannot implement your logic otherwise
🌐
GitHub
github.com β€Ί pola-rs β€Ί polars β€Ί issues β€Ί 3484
Make it easy to apply a user-defined function to a DataFrame in Rust Β· Issue #3484 Β· pola-rs/polars
May 24, 2022 - Describe your feature request Both pandas DataFrame and Spark DataFrame support applying a user-defined function which take a row or multiple scalar values as input. Can we support the same in pola...
Author Β  pola-rs
🌐
Polars
docs.pola.rs β€Ί py-polars β€Ί html β€Ί reference β€Ί dataframe β€Ί api β€Ί polars.DataFrame.map_rows.html
polars.DataFrame.map_rows β€” Polars documentation
The UDF will receive each row as a tuple of values: udf(row). Implementing logic using a Python function is almost always significantly slower and more memory intensive than implementing the same logic using the native expression API because: The native expression engine runs in Rust; UDFs run in Python. Use of Python UDFs forces the DataFrame to be materialized in memory. Polars-native expressions can be parallelised (UDFs typically cannot).
🌐
StudyRaid
app.studyraid.com β€Ί en β€Ί read β€Ί 11455 β€Ί 359017 β€Ί applying-functions-to-columns
Understand applying functions to columns
You can transform data using built-in functions or custom operations. The following example demonstrates how to apply basic mathematical operations and string transformations to columns. We create a new column by multiplying values and perform string operations on existing columns: ... import polars as pl df = pl.DataFrame({ "numbers": [1, 2, 3, 4], "text": ["a", "b", "c", "d"] }) # Apply multiple transformations in a single operation transformed_df = df.with_columns([ (pl.col("numbers") * 2).alias("doubled"), # Multiply numbers by 2 pl.col("text").str.to_uppercase().alias("upper_text") # Convert text to uppercase ])
🌐
Reddit
reddit.com β€Ί r/dataengineering β€Ί is there a "correct" way to convert a pandas function to polars?
r/dataengineering on Reddit: Is there a "correct" way to convert a Pandas Function to Polars?
May 22, 2024 -

Finally broke down and decided I should learn Polars. Been a few hiccups, but going well. One I ran into was this example:

In Pandas I have a function which splits a string every 8 characters, adds ".TIF" and returns it as a string that I can later convert to a list with ast

def split_and_add_tif(text):

return [','.join([text[I:8] + '.TIF' for i in range(0, len(text, 8)])]

to apply this with Pandas I'd simply do:

df['FileList'] = df['FileList'].apply(split_and_add_tif)

However in Polars it appears I need to do this:

df = df.with_columns(

df['FileList'].map_elements(split_and_add_tif, return_dtype = list).alias('FileList')

)

Is this the correct way to do this? Does anyone have a good resource for going from Pandas Functions to Polars? Still a bit confused on the difference between map_rows and map_elements. Any advice/pointers are welcomed.

🌐
Pola-rs
pola-rs.github.io β€Ί polars β€Ί py-polars β€Ί html β€Ί reference β€Ί dataframe β€Ί api β€Ί polars.DataFrame.apply.html
polars.DataFrame.apply β€” Polars documentation
Deprecated since version 0.19.0: This method has been renamed to DataFrame.map_rows(). ... Custom function or lambda. ... Output type of the operation. If none given, Polars tries to infer the type.
🌐
TypeThePipe
typethepipe.com β€Ί vizs-and-tips β€Ί python-polars-suggest-efficient-expressions-lambda-function
Polars new feature. Suggest more efficient Polars method for apply lambda functions | TypeThePipe
July 20, 2023 - Lasts days were thrilling in the Polars repo. One of the most celebrated improvements that was merged yestarday is about the usage of apply function to map udf to columns.
🌐
Real Python
realpython.com β€Ί polars-groupby
How to Group Data Using Polars .group_by() – Real Python
March 1, 2025 - Window functions in Polars allow you to perform aggregations over groups while retaining the original DataFrame’s structure. You use them by applying aggregation functions with .over(), which assigns the aggregated value to each row in the group.
🌐
Rust Programming Language
users.rust-lang.org β€Ί t β€Ί in-polars-how-to-apply-a-custon-function-to-a-column-of-strings β€Ί 108687
In polars, how to apply a custon function to a column of strings? - The Rust Programming Language Forum
March 21, 2024 - Hi, After looking at polars documentation, I'm having a really hard time to apply a custom function (taking a string, doing operations not available in polars and returning a new string) and get the result as a Vect. T…
🌐
Polars
docs.pola.rs β€Ί api β€Ί python β€Ί version β€Ί 0.19 β€Ί reference β€Ί series β€Ί api β€Ί polars.Series.apply.html
polars.Series.apply β€” Polars documentation
Apply a custom/user-defined function (UDF) over elements in this Series Β· Deprecated since version 0.19.0: This method has been renamed to Series.map_elements()