如何用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的原生方法,不需要套rollingdf.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()
关键知识点总结
- 排序是前提:时间序列计算必须确保日期是按顺序排列的,否则
diff()会计算错误的行差值 - 分组是核心:必须按地区(州/县)分组,避免跨地区的病例差值计算
diff()是最优解:pandas的diff()方法专门用来计算前后行的差值,比手动用rolling或subtract更简洁可靠
内容的提问来源于stack exchange,提问作者sc4s2cg
相关产品推荐
相关产品推荐

