You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas层级透视表:获取各date-hr下计数最大的Channel

Pandas透视表转换:提取每个date-hr下计数最高的Channel及计数值

没问题,我来帮你搞定这个数据转换需求。先咱们对齐一下数据情况和目标,然后一步步实现:

数据背景回顾

你的原始DataFrame结构如下:

df.head().info()

输出:

RangeIndex: 5 entries, 0 to 4
Data columns (total 4 columns):
 id 5 non-null object
 date-hr 5 non-null object
 channel 5 non-null object
 hr 5 non-null int64
dtypes: int64(1), object(3)

数据样例(简化后):

User-ID | Date-hr | Channel | Hr
U1      | D1-10   | C1      | 10
U1      | D1-11   | C2      | 11
U1      | D1-10   | C1      | 10
U1      | D1-10   | C3      | 10
U1      | D1-10   | C1      | 10
U1      | D1-11   | C3      | 11
U1      | D1-11   | C2      | 11
...

你已经完成了第一步透视,得到了每个用户、每个date-hr下不同channel的计数,现在需要把每个date-hr列转换为该时段内计数最高的channel + 对应计数值的元组格式。


方法一:基于透视表分组处理

这是最直接的思路,先构建基础透视表,再对每个date-hr列组提取最大值信息:

import pandas as pd

# 1. 构建基础透视表:行是User-ID,列是(date-hr, channel),值是计数
pivot_df = df.pivot_table(
    index='id',
    columns=['date-hr', 'channel'],
    values='hr',
    aggfunc='count',
    fill_value=0
)

# 2. 定义函数:对单个date-hr下的所有channel列,提取每行的最大计数及对应channel
def get_top_channel_info(col_group):
    # col_group是当前date-hr下的所有channel列组成的DataFrame
    max_counts = col_group.max(axis=1)
    # 找到计数最大的channel:idxmax返回的是(date-hr, channel)索引,取第二个元素
    top_channels = col_group.idxmax(axis=1).str[1]
    # 组合成元组
    return pd.Series(list(zip(top_channels, max_counts)), index=col_group.index)

# 3. 按date-hr列分组(第一层列索引),应用函数
result_df = pivot_df.groupby(level=0, axis=1).apply(get_top_channel_info)

运行后result_df的格式就完全符合你的需求了,比如U1行的D1-10列会是('C1', 3),D1-11列是('C2', 2)。


方法二:堆叠透视表后再重组

如果你觉得分组处理有点绕,也可以用“堆叠-提取-重组”的思路:

import pandas as pd

# 1. 先做基础透视表(和方法一一样)
pivot_df = df.pivot_table(
    index='id',
    columns=['date-hr', 'channel'],
    values='hr',
    aggfunc='count',
    fill_value=0
)

# 2. 把date-hr从列索引转到行索引,变成(id, date-hr)为复合索引,channel为列
stacked_df = pivot_df.stack(level=0)

# 3. 提取每个(id, date-hr)组合下的最大计数channel和对应值
top_channels = stacked_df.idxmax(axis=1)
top_counts = stacked_df.max(axis=1)

# 4. 组合成元组,再重新透视回date-hr为列的格式
result_df = pd.DataFrame(
    {'top_info': list(zip(top_channels, top_counts))},
    index=stacked_df.index
).unstack(level=1)

# 5. 去掉多余的顶层列名(因为unstack后会有'top_info'作为顶层列)
result_df.columns = result_df.columns.droplevel(0)

这个方法的逻辑更直观:先把date-hr放到行里,让每个用户+时段的组合独立成行,找到最大值后再把date-hr转回列。


两种方法都能得到你想要的结果,你可以根据自己的习惯选择。如果你的数据量很大,方法一的效率会稍微高一点,因为不需要频繁转换索引结构。

内容的提问来源于stack exchange,提问作者Nikhil Verma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:24:17