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

如何计算Pandas中特定年份创建文档的timespan列总和?

解决特定年份timespan总和计算返回0的问题

看起来你遇到的问题主要来自两个潜在的点:意外修改原始DataFrame的列,或者**timespan列的解析逻辑存在问题**。下面一步步帮你排查和解决:

1. 核心问题:不要修改全局的creation列

你的time函数里直接执行了my_ocan['creation'] = pd.DatetimeIndex(my_ocan['creation']).year,这会把原始DataFrame中creation列的datetime类型直接替换成整数年份。不仅会污染原始数据,还可能导致后续多次调用函数时出现逻辑混乱(比如第二次调用时,creation已经是整数,再用DatetimeIndex处理会出错)。

更稳妥的做法是不修改原始列,而是在筛选时动态提取年份:

def do_get_citations_per_year(year):
    # 直接通过dt.year提取年份进行筛选,不修改原始DataFrame
    filtered_data = my_ocan[my_ocan['creation'].dt.year == year]
    doc_count = len(filtered_data)
    # 计算timespan总和
    total_timespan = filtered_data['timespan'].sum()
    # 计算平均timespan(处理除数为0的情况)
    avg_timespan = total_timespan / doc_count if doc_count > 0 else 0
    return (doc_count, avg_timespan)

2. 检查timespan的解析逻辑

你提到timespan最终是int64类型,但如果你的parse函数没有正确解析原始的周期字符串(比如示例中的P2Y),就会导致所有timespan值为0,自然求和结果也是0。

比如针对P2Y这类ISO 8601周期格式,你可以这样写parse函数:

def parse(period_str):
    # 提取周期字符串中的数字部分
    if not period_str or not isinstance(period_str, str):
        return 0
    # 过滤出所有数字字符并转换为整数
    num_part = ''.join([c for c in period_str if c.isdigit()])
    return int(num_part) if num_part else 0

测试一下这个函数:parse("P2Y")会返回2,这样timespan列就会有有效数值,求和也能得到正确结果。

3. 优化建议:避免使用全局变量

全局变量my_ocan容易导致数据被意外修改,建议把处理后的DataFrame作为参数传递给统计函数,让代码更健壮:

def do_process_citation_data(f_path):
    my_ocan = pd.read_csv(f_path, names=['oci', 'citing', 'cited', 'creation', 'timespan', 'journal_sc', 'author_sc'], parse_dates=['creation', 'timespan'])
    my_ocan = my_ocan.iloc[1:]  # 移除表头行
    my_ocan['creation'] = pd.to_datetime(my_ocan['creation'], format="%Y-%m-%d", yearfirst=True)
    my_ocan['timespan'] = my_ocan['timespan'].apply(parse)
    return my_ocan

def do_get_citations_per_year(df, year):
    filtered_data = df[df['creation'].dt.year == year]
    doc_count = len(filtered_data)
    total_timespan = filtered_data['timespan'].sum()
    avg_timespan = total_timespan / doc_count if doc_count > 0 else 0
    return (doc_count, avg_timespan)

# 使用示例
processed_df = do_process_citation_data("citations.csv")
year_1985_stats = do_get_citations_per_year(processed_df, 1985)
print(f"1985年文档数:{year_1985_stats[0]},平均timespan:{year_1985_stats[1]}")

这样修改后,既保护了原始数据,也让函数的复用性更强。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 17:32:35