如果你像这样编写Polars代码
for col in df.columns:
do stuff
则停止!!!!
在 Polars 中,避免使用显式循环遍历列是非常推荐的做法,因为显式循环会破坏并行化,在大规模数据集上效率低下。Polars 提供了一系列向量化操作和方法,可以让你以更高效的方式处理数据。
相反,首先应使用表达式,然后Polars将为您并行处理列循环。
例如,如果我们想要计算每一列中唯一值的数量,我们可以这样做:
import polars as pl
df = pl.DataFrame({
'A': [-1, 2, 3],
'B': [4, 5, -6],
'C': [7, -8, 9]
})
df = df.with_columns((pl.col('A') + pl.col('B')).alias('SumAB'))
df.select(pl.all().n_unique())
或者,如果我们想要计算唯一值的数量,但仅针对字符串(Utf8)列,我们可以这样做:
df.select(pl.col(pl.Utf8)).select(pl.all().n_unique())
如果我们想要将所有数值列标准化,可以这样:
df = df.with_columns(
[(pl.col(col) - pl.col(col).mean()) / pl.col(col).std() for col in df.select(pl.col(pl.Int64)).columns]
)
也可以使用聚合函数。 Polars 提供了许多内置的聚合函数,如 sum
, mean
, min
, max
, median
, quantile
, std
, var
等,可以直接应用于列上。例如,计算列的平均值:
average = df.select(pl.mean('A'))['A'][0]
当你需要按某个或某些列分组并对每组应用操作时,可以使用 groupby
方法。例如,按类别列分组计算数值列的平均值:
df_grouped = df.groupby('category').agg(pl.mean('value'))
使用 apply
方法: 虽然 apply
方法有时可能涉及一些形式的循环,但它是在列级别而非行级别上应用函数,通常比逐行应用更高效。例如,对整列应用自定义函数:
df = df.with_columns(pl.col('A').apply(lambda x: x * 2))
实在不行,还可以使用 map
和 map_elements
方法: map
和 map_elements
方法可以分别用于 Series 和 DataFrame 上,它们允许你应用 UDF(用户定义函数)。这些方法在内部已经优化,比普通的 Python 循环快得多。
map方法示例:假设我们有一个DataFrame,其中包含人员的姓名和出生日期,我们想创建一个新的列,该列包含每个人的年龄。
import polars as pl
from datetime import datetime
# 创建示例DataFrame
df = pl.DataFrame({
'name': ['Alice', 'Bob', 'Charlie'],
'birthdate': ['1990-01-01', '1985-05-20', '1992-12-31']
})
# 将birthdate列转换为日期类型
df = df.with_columns(pl.col('birthdate').str.strptime(pl.Date, '%Y-%m-%d'))
# 定义一个计算年龄的函数
def calculate_age(birthdate):
today = datetime.now().date()
age = today.year - birthdate.year - ((today.month, today.day) < (birthdate.month, birthdate.day))
return age
# 使用map方法应用calculate_age函数
df = df.with_columns(pl.col('birthdate').map(calculate_age).alias('age'))
print(df)
比如用map_elements应用abs函数将DataFrame中的数值列转换为绝对值:
df = df.with_columns([pl.col(column).map_elements(abs) for column in df.columns])
最后,如果需要合并 DataFrame,可以使用 join
方法,这通常比使用循环和条件语句更高效。
假设我们有两个 DataFrame,一个包含员工信息,另一个包含部门信息。我们将使用 join
方法基于部门ID连接这两个表。
import polars as pl
# 创建第一个DataFrame,包含员工信息
employees_df = pl.DataFrame({
'employee_id': [1, 2, 3, 4],
'name': ['Alice', 'Bob', 'Charlie', 'David'],
'department_id': [10, 20, 10, 30]
})
# 创建第二个DataFrame,包含部门信息
departments_df = pl.DataFrame({
'department_id': [10, 20, 30],
'department_name': ['HR', 'IT', 'Finance']
})
# 使用内连接(inner join)基于'department_id'连接两个DataFrame
joined_df = employees_df.join(departments_df, on='department_id', how='inner')
print(joined_df)