DataFrame列值条件提取:同一用户分组存在至少1个非nan值即取用
实现方案
第一步:优先做内存优化
700万行数据建议先优化DataFrame存储类型,可降低60%以上内存占用:
import pandas as pd import numpy as np # 假设用户唯一标识列名为user_id # 类别型字段转category类型大幅省内存 df['user_id'] = df['user_id'].astype('category') # 把城市、设备、语言等用户固定属性列加入列表统一处理 fix_attr_cols = ['city', 'device', 'language'] for col in fix_attr_cols: df[col] = df[col].astype('category')
第二步:两种实现路径按需选择
路径1:直接生成用户画像维度表(内存效率最高)
不需要修改原700万行的行为表,直接输出40万行的用户级属性表,是生成用户画像的最优选择:
def pick_valid_value(series): # 取分组内第一个非空值,全为空则返回缺失值标记 cleaned = series.dropna() return cleaned.iloc[0] if not cleaned.empty else pd.NA # observed=True仅聚合存在的用户分类,避免生成冗余数据 user_profile = df.groupby('user_id', observed=True)[fix_attr_cols].agg(pick_valid_value).reset_index()
路径2:填充原行为表的缺失值
如果需要补全原表所有行的属性缺失值,可使用transform实现:
for col in fix_attr_cols: df[col] = df.groupby('user_id', observed=True)[col].transform( lambda x: x.ffill().bfill() )
性能说明
以上方案在普通8G内存设备上可正常运行,pandas的groupby操作经过Cython优化,不会出现Python遍历的性能瓶颈。如果需要进一步提速,可在读取数据时指定dtype_backend='pyarrow'使用pyarrow作为存储后端,整体运行速度可提升30%以上。
内容的提问来源于stack exchange,提问作者Kami
相关产品推荐
相关产品推荐

