如何将Pandas DataFrame按当月天数进行除法运算?
问题:月度DataFrame数据除以对应月份天数后结果全为NaN的解决办法
原DataFrame示例
var1 var2 Time 2000-01-31 100 200 2000-02-28 340 210 2000-03-31 590 220 ... 2001-10-31 1290 101 2001-11-30 1188 100 2001-12-31 1000 100
需求说明
需要创建新DataFrame,将原数据中每一行的值除以对应月份的天数:
- 2000-01-31对应数据除以31
- 2000-02-28对应数据除以28
- 2001-11-30对应数据除以30
- 以此类推
目标DataFrame示例
var1_new var2_new Time 2000-01-31 3.22 6.45 2000-02-28 12.14 7.5 2000-03-31 19.03 7.09 ... 2001-10-31 41.61 3.26 2001-11-30 39.6 3.33 2001-12-31 32.26 3.23
用户代码及问题
用户尝试的代码执行后结果全为NaN,代码如下:
df.index = pd.to_timedelta(df["Time"], unit='s') df.index += datetime.strptime(initial_datetime, "%Y-%m-%d") df_D=df.resample("D").sum() df_M=df_D.resample("M").sum() df_M["Months"] = df_M.index df2["DiM"] = pd.DataFrame(pd.to_datetime(df_M["Months"]).dt.daysinmonth) df_M = df_M.drop(['Months'],axis=1) df_New = df_M / df2["DiM"]
问题分析
- 索引处理错误:原DataFrame的
Time已经是索引,代码中却尝试访问df["Time"](列),会触发KeyError;用timedelta转换索引属于多余操作,反而打乱了原有的日期索引逻辑。 - 不必要的重采样:原数据已经是月度末的汇总值,不需要先按天再按月重采样求和,这一步会篡改原始数据。
- df2未初始化+索引不匹配:代码直接给
df2["DiM"]赋值,但df2并未提前创建;即使创建,df_M和df2["DiM"]的索引大概率不匹配,导致除法运算后全为NaN。
正确解法
直接基于原DataFrame处理,步骤简洁高效:
# 先确保索引是datetime类型(如果原始索引是字符串格式的话) df.index = pd.to_datetime(df.index) # 提取每个日期对应的当月天数 days_in_month = df.index.daysinmonth # 计算新数据并重命名列 df_new = df.div(days_in_month, axis=0).rename(columns={'var1': 'var1_new', 'var2': 'var2_new'}) # 可选:保留两位小数,和示例格式对齐 df_new = df_new.round(2)
执行后即可得到目标格式的DataFrame,不会出现NaN问题。
内容的提问来源于stack exchange,提问作者Yogi
相关产品推荐
相关产品推荐

