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

如何用Pandas计算时间序列DataFrame中每日新增病例数?

解决NYT新冠数据每日新增病例计算问题

嘿,我来帮你搞定这个计算每日新增新冠病例的问题!先理清楚核心需求:从累计病例数得到每日新增,本质是对每个地区(州/县)的时间序列做「当前值 - 前一天值」的计算。你之前尝试的方法没找对正确的操作顺序,咱们一步步拆解:

先分析你遇到的报错原因

你尝试的几个方法都是逻辑顺序错了,导致报错:

  • df.resample('2d').diff():resample返回的是重采样器对象,它本身没有diff()方法,得先完成重采样聚合,再对结果用diff(),或者先算差值再重采样
  • df.resample('1d').agg(np.subtract):np.subtract需要两个输入参数,但agg是对组内数据做聚合操作(比如求和、均值),没法直接用来做前后行的减法
  • df.rolling(2).diff():Rolling对象确实没有diff()方法,diff()是Series/DataFrame的原生方法,不需要套rolling
  • df.rolling('2').agg(np.subtract):同样,rolling的agg用subtract缺少第二个参数,逻辑上就不成立

正确的解决方案(手动/函数实现)

核心思路是:先按地区(州/县)分组 → 确保时间序列按日期排序 → 对累计病例列用diff()计算前后行差值

第一步:处理样本数据

先拿你提供的样本数据测试,代码如下:

import pandas as pd
import numpy as np
from datetime import date as dt_date

# 你的样本数据
sample_df = pd.DataFrame(
    data={
        'state': ['Alabama','Alabama','Alabama','Alabama','Alabama'],
        'date': [dt_date(2020,3,13), dt_date(2020,3,14), dt_date(2020,3,15), dt_date(2020,3,16), dt_date(2020,3,17)],
        'covid_cases': [1.2,2.0,2.9,3.6,3.9]
    }
)

# 1. 按state和date排序(关键!确保时间序列是连续的)
sample_df = sample_df.sort_values(by=['state', 'date'])

# 2. 按state分组,对累计病例列计算diff,得到每日新增
sample_df['new_covid_cases'] = sample_df.groupby('state')['covid_cases'].diff()

# 输出结果,和你期望的一致
print(sample_df)

运行后会得到你想要的输出:第一天因为没有前一天数据,新增为NaN,后面的数值都是对应日期的新增病例。

第二步:处理真实NYT数据集

直接套用上面的逻辑到真实数据上:

# 读取NYT数据(你提供的代码)
df = pd.read_csv('https://raw.githubusercontent.com/nytimes/covid-19-data/master/us-counties.csv', parse_dates=['date'])

# 按state和date取病例均值(保留你的原有操作)
df_state = df.groupby(['state','date'])[['cases']].mean().reset_index()

# 核心步骤:排序 + 分组计算新增
df_state = df_state.sort_values(by=['state', 'date'])
df_state['new_cases'] = df_state.groupby('state')['cases'].diff()

# 可选:如果想把第一天的NaN替换为0
# df_state['new_cases'] = df_state['new_cases'].fillna(0)

扩展:结合滚动均值/重采样

如果你需要结合之前提到的滚动均值、2天重采样操作,可以在计算新增后进行:

# 示例1:计算新增病例的7天滚动均值
df_state['new_cases_7d_avg'] = df_state.groupby('state')['new_cases'].rolling(7).mean().reset_index(level=0, drop=True)

# 示例2:按2天重采样,计算每2天的新增病例总和
# 先把date设为索引,再分组重采样
df_state_indexed = df_state.set_index('date')
df_2d_sum = df_state_indexed.groupby('state')['new_cases'].resample('2d').sum().reset_index()

关键知识点总结

  1. 排序是前提:时间序列计算必须确保日期是按顺序排列的,否则diff()会计算错误的行差值
  2. 分组是核心:必须按地区(州/县)分组,避免跨地区的病例差值计算
  3. diff()是最优解:pandas的diff()方法专门用来计算前后行的差值,比手动用rolling或subtract更简洁可靠

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 21:12:49