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

使用Pandas统计活跃订阅数并绘图时遇KeyError问题求助

嘿,我来帮你搞定这个订阅数曲线的问题!你遇到的KeyError大概率是日期索引的类型不匹配,或者累加时没处理好日期格式的一致性。咱们一步步来解决:

第一步:先把原始数据的日期类型捋顺

首先得确保你的df里的start_date索引是datetime类型——如果是字符串格式的日期,后续操作很容易触发KeyError。先检查并转换:

import pandas as pd

# 检查索引类型
print(df.index.dtype)
# 如果不是datetime64,就转换为datetime类型
if not pd.api.types.is_datetime64_dtype(df.index):
    df.index = pd.to_datetime(df.index)
第二步:生成覆盖所有活跃期的完整日期序列

先算出所有订阅的最早起始日和最晚结束日,再生成这个区间内的每日日期,作为后续统计的基础:

# 计算每个订阅的结束日期(起始日+时长)
df['end_date'] = df.index + pd.to_timedelta(df['duration'], unit='D')

# 找到全局的时间边界
min_active_date = df.index.min()
max_active_date = df['end_date'].max()

# 生成完整的每日日期序列
full_date_range = pd.date_range(start=min_active_date, end=max_active_date, freq='D')

# 初始化订阅数统计的DataFrame
subscribers = pd.DataFrame({'Number': 0}, index=full_date_range)
subscribers.index.name = 'Date'
第三步:正确累加每个订阅的活跃日期

之前的KeyError很可能是直接用loc赋值时,目标日期不在统计DataFrame的索引里。咱们用add方法来安全累加,自动处理日期匹配问题:

for start_day, row in df.iterrows():
    # 生成当前订阅的所有活跃日期
    active_days = pd.date_range(start=start_day, end=row['end_date'], freq='D')
    # 创建临时序列,这些日期的订阅数加1
    temp_counts = pd.Series(1, index=active_days)
    # 用add方法累加,fill_value=0避免找不到日期的报错
    subscribers['Number'] = subscribers['Number'].add(temp_counts, fill_value=0)
第四步:绘制订阅数变化曲线

现在统计结果已经正确生成,直接绘图即可:

import matplotlib.pyplot as plt

subscribers['Number'].plot(figsize=(10,6), title='Active Subscribers Over Time')
plt.xlabel('Date')
plt.ylabel('Number of Active Subscribers')
plt.grid(alpha=0.3)
plt.show()
(进阶)大数据量下的高效写法

如果你的订阅数据量很大,循环会很慢,推荐用explode+value_counts的无循环写法,既高效又不会触发KeyError:

# 为每个订阅生成活跃日期范围
df['active_dates'] = df.apply(lambda x: pd.date_range(x.name, x['end_date'], freq='D'), axis=1)
# 把所有日期展开成单列
all_active_dates = df['active_dates'].explode()
# 统计每日的订阅数并排序
subscribers = all_active_dates.value_counts().sort_index().reset_index()
subscribers.columns = ['Date', 'Number']

为啥之前会出KeyError?

大概率是你尝试赋值的日期不在subscribers的索引里——比如生成日期范围时漏了部分日期,或者原始日期是Timestamp类型,但subscribers的索引是字符串格式。上面的方法通过统一日期类型、生成完整日期范围、用add/explode处理匹配,完美规避了这个问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 10:38:51