如何处理用户访问DataFrame:将大于0的值替换为列名并生成按日期的用户列表
解决方案
可以用Pandas的melt或stack方法快速实现需求,以下是两种简洁的实现方式:
方法一:使用melt重塑数据
先将宽表转为窄表,再筛选有效访问记录,最后整理成目标格式:
import pandas as pd # 构造示例数据 df = pd.DataFrame({ 'Codes': ['A1AA', 'A1BB', 'A1CC', 'A2DD', 'A1EE', 'A1AA'], '2022-09-04': [1, 0, 5, 0, 0, 0], '2022-09-03': [0, 0, 0, 5, 1, 0], '2022-09-02': [0, 2, 0, 0, 0, 1] }) # 宽表转窄表,拆分日期和访问次数 melted_df = df.melt(id_vars='Codes', var_name='Dates', value_name='Visits') # 筛选访问次数>0的记录,保留目标列 result = melted_df[melted_df['Visits'] > 0][['Dates', 'Codes']] # 按日期降序排序,匹配预期输出顺序 result = result.sort_values('Dates', ascending=False).reset_index(drop=True) print(result)
输出结果:
Dates Codes 0 2022-09-04 A1AA 1 2022-09-04 A1CC 2 2022-09-03 A2DD 3 2022-09-03 A1EE 4 2022-09-02 A1BB 5 2022-09-02 A1AA
方法二:使用stack快速处理
利用stack将列转成行,自动压缩无效记录:
import pandas as pd # 构造示例数据并将Codes设为索引 df = pd.DataFrame({ 'Codes': ['A1AA', 'A1BB', 'A1CC', 'A2DD', 'A1EE', 'A1AA'], '2022-09-04': [1, 0, 5, 0, 0, 0], '2022-09-03': [0, 0, 0, 5, 1, 0], '2022-09-02': [0, 2, 0, 0, 0, 1] }).set_index('Codes') # 转置列索引为行,筛选有效访问记录,重置索引并调整列名 result = df.stack()[df.stack() > 0].reset_index() result.columns = ['Codes', 'Dates'] # 调整列顺序并排序 result = result[['Dates', 'Codes']].sort_values('Dates', ascending=False).reset_index(drop=True) print(result)
输出与方法一完全一致。
核心逻辑说明
- 宽表转窄表:两种方法都是将以日期为列的结构,转换为每行对应「用户-日期-访问次数」的窄表,方便后续筛选。
- 筛选有效访问:通过布尔索引过滤掉访问次数为0的无效记录。
- 格式整理:调整列顺序、排序,让结果匹配预期输出。
内容的提问来源于stack exchange,提问作者Harish reddy
相关产品推荐
相关产品推荐

