将Pandas跨受众分析代码转换为Polars的技术求助
Pandas转Polars:实现受众交叉客户统计分析
核心逻辑说明
针对需求:统计单个受众的独立DNI数,以及所有受众组合的交叉客户数、占总独立客户的比例,以下是对应Polars实现代码,对齐常见的Pandas业务逻辑。
示例数据与单受众统计(补充验证你已实现的部分)
import polars as pl # 构造与Pandas对齐的示例数据 df = pl.DataFrame({ 'DNI': ['123', '456', '789', '123', '456'], 'Audience_A': [1, 1, 0, 1, 0], 'Audience_B': [0, 1, 1, 0, 1], 'Audience_C': [1, 0, 1, 0, 0] }) # 单受众独立DNI统计 unique_dni_per_audience = ( df .melt(id_vars='DNI', value_vars=df.columns[1:], variable_name='Audience', value_name='Is_Member') .filter(pl.col('Is_Member') == 1) .group_by('Audience') .agg(pl.col('DNI').n_unique().alias('Unique_DNI_Count')) ) print(unique_dni_per_audience)
受众组合交叉分析实现
利用itertools.combinations生成所有可能的受众组合,结合Polars的all_horizontal实现多条件筛选,完成交叉客户数统计:
from itertools import combinations # 获取所有受众列名 audience_cols = df.columns[1:] # 计算总独立DNI数 total_unique_dni = df.select(pl.col('DNI').n_unique()).item() cross_results = [] # 遍历所有组合长度(从1个受众到全部受众) for combo_length in range(1, len(audience_cols)+1): # 生成当前长度的所有受众组合 for combo in combinations(audience_cols, combo_length): # 构建筛选条件:组合中所有受众均为会员(值为1) filter_condition = pl.all_horizontal(pl.col(col) == 1 for col in combo) # 统计符合条件的独立DNI数量 cross_count = ( df .filter(filter_condition) .select(pl.col('DNI').n_unique()) .item() ) # 计算占总客户的比例 cross_ratio = cross_count / total_unique_dni # 存入结果列表 cross_results.append({ 'Audience_Combo': '+'.join(combo), 'Unique_DNI_Count': cross_count, 'Ratio_to_Total': round(cross_ratio, 4) }) # 转换为Polars DataFrame cross_analysis_df = pl.DataFrame(cross_results) print(cross_analysis_df)
大数据集优化方案
如果数据量较大,建议先对DNI去重(假设同一DNI的受众标记一致),减少重复计算:
# 去重:保留每个DNI的唯一受众记录 unique_customer_df = df.unique(subset='DNI') total_unique_dni = unique_customer_df.height # 去重后行数即为总独立客户数 cross_results = [] for combo_length in range(1, len(audience_cols)+1): for combo in combinations(audience_cols, combo_length): filter_condition = pl.all_horizontal(pl.col(col) == 1 for col in combo) cross_count = unique_customer_df.filter(filter_condition).height cross_ratio = cross_count / total_unique_dni cross_results.append({ 'Audience_Combo': '+'.join(combo), 'Unique_DNI_Count': cross_count, 'Ratio_to_Total': round(cross_ratio, 4) }) cross_analysis_df = pl.DataFrame(cross_results)
内容的提问来源于stack exchange,提问作者Joel Medina
相关产品推荐
相关产品推荐

