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

高效实现:统计用户每段新订阅期首次观看的内容title

解决大数据量下订阅期首次观看内容统计问题

核心思路

放弃循环,用Pandas的高效时间匹配和分组聚合方法,避免内存溢出。以下是分步实现方案:

1. 数据预处理:统一时间格式+优化内存

先确保所有时间列都是datetime类型,同时优化数据类型降低内存占用:

import pandas as pd

# 处理订阅DF(记为df_sub)
df_sub['start_ts'] = pd.to_datetime(df_sub['start_ts'])
df_sub['end_ts'] = pd.to_datetime(df_sub['end_ts'])
df_sub['ids'] = df_sub['ids'].astype('category')

# 处理观看记录DF(记为df_view)
df_view['ts_start'] = pd.to_datetime(df_view['ts_start'])
df_view['ids'] = df_view['ids'].astype('category')
df_view['title'] = df_view['title'].astype('category')

2. 高效匹配订阅期与观看记录

用merge_asof按用户ID和时间范围匹配,这比普通merge或循环快几个数量级:

# 先对两个DF按ids和时间列排序(merge_asof要求)
df_sub_sorted = df_sub.sort_values(['ids', 'start_ts'])
df_view_sorted = df_view.sort_values(['ids', 'ts_start'])

# 匹配:每个观看记录对应到它所属的订阅期
df_merged = pd.merge_asof(
    df_view_sorted,
    df_sub_sorted,
    left_on='ts_start',
    right_on='start_ts',
    by='ids',
    direction='backward',  # 找ts_start之前最近的未过期订阅期
    allow_exact_matches=True
)

# 过滤掉观看时间超出订阅期的记录(避免匹配到已过期的订阅)
df_merged = df_merged[df_merged['ts_start'] <= df_merged['end_ts']]

3. 提取每个订阅期内的首次观看内容

按用户ID和订阅期(用start_ts标识唯一订阅期)分组,取每组中最早的观看记录对应的title:

# 按ids和start_ts分组,保留每个组中ts_start最小的行
first_watches = df_merged.sort_values('ts_start').groupby(['ids', 'start_ts']).first().reset_index()

# 提取首次观看的title列表
first_titles = first_watches['title']

4. 统计title频次

直接用value_counts统计即可:

title_stats = first_titles.value_counts().reset_index()
title_stats.columns = ['title', 'count']

额外性能优化建议

  • 如果内存仍紧张,用dask.dataframe替代Pandas,它支持分块处理大数据集,无需一次性加载全部数据到内存。
  • 可先过滤df_view中重复的(ids, ts_start, title)记录,减少匹配的数据量。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 05:36:12