Pandas按月重采样转日度数据后提取月中值报错排查
问题解决:提取日度数据中每月中间日期的值
问题说明
将月度输入数据通过resample('D')和三次插值转换为日度数据后,尝试提取每月中间日期对应的数据时,触发错误:AttributeError: 'DatetimeIndex' object has no attribute 'days'。
出错代码
import pandas as pd df=pd.read_excel(input_file, sheet_name='mthly', usecols='A:D', na_values='ND', index_col=0, header=0) df.index.names = ['Period'] df.index = pd.to_datetime(df.index) q= pd.Series(df[series], index=df.index) d = q.resample('D').interpolate(method='cubic') m=d[lambda x: x.index.days==round(x.index.daysinmonth/2)]
输入月度数据
Period Values Jan-22 1 Feb-22 3 Mar-22 7 Apr-22 5 May-22 4
重采样插值后的日度数据示例
1/1/2022 0:00 1 2/1/2022 0:00 0.884487406 3/1/2022 0:00 0.78564987 4/1/2022 0:00 0.703003964 5/1/2022 0:00 0.636066259 6/1/2022 0:00 0.584353327 7/1/2022 0:00 0.547381739 8/1/2022 0:00 0.524668066 9/1/2022 0:00 0.51572888 10/1/2022 0:00 0.520080751 11/1/2022 0:00 0.537240252 12/1/2022 0:00 0.566723954 13/1/2022 0:00 0.608048428 14/1/2022 0:00 0.660730245 15/1/2022 0:00 0.724285976 16/1/2022 0:00 0.798232194 17/1/2022 0:00 0.882085469 18/1/2022 0:00 0.975362373 19/1/2022 0:00 1.077579477 20/1/2022 0:00 1.188253353 21/1/2022 0:00 1.306900571 22/1/2022 0:00 1.433037703 23/1/2022 0:00 1.566181321 24/1/2022 0:00 1.705847996 25/1/2022 0:00 1.851554299 26/1/2022 0:00 2.002816801 27/1/2022 0:00 2.159152074 28/1/2022 0:00 2.32007669 29/1/2022 0:00 2.485107218 30/1/2022 0:00 2.653760232 31/1/2022 0:00 2.825552302 ...
期望输出
16/1/2022 0:00 0.798232194 14/2/2022 0:00 5.289522142 ...
错误原因与修复代码
错误原因
DatetimeIndex没有days属性,获取每月日期需用单数形式day;- 旧版pandas中
daysinmonth无法直接对整个索引矢量化访问,需调整处理方式。
修复后代码(适配pandas 1.1+)
import pandas as pd df=pd.read_excel(input_file, sheet_name='mthly', usecols='A:D', na_values='ND', index_col=0, header=0) df.index.names = ['Period'] df.index = pd.to_datetime(df.index) # 注意:将series替换为实际列名,比如示例中的'Values' q= pd.Series(df['Values'], index=df.index) d = q.resample('D').interpolate(method='cubic') # 修复条件判断:用day获取日部分,结合daysinmonth计算中间日期 m = d[d.index.day == round(d.index.daysinmonth / 2)]
兼容旧版pandas的代码
如果你的pandas版本不支持矢量化daysinmonth,可改用apply处理:
import pandas as pd df=pd.read_excel(input_file, sheet_name='mthly', usecols='A:D', na_values='ND', index_col=0, header=0) df.index.names = ['Period'] df.index = pd.to_datetime(df.index) q= pd.Series(df['Values'], index=df.index) d = q.resample('D').interpolate(method='cubic') # 逐个判断每个日期是否为当月中间日 m = d[d.index.to_series().apply(lambda dt: dt.day == round(dt.daysinmonth / 2))]
代码解释
d.index.day:提取每个日期的日部分(如1月16日返回16);d.index.daysinmonth:获取每个日期所在月份的总天数(如2022年2月返回28);- 通过两者的匹配计算,精准筛选出每月中间日期对应的数据。
内容的提问来源于stack exchange,提问作者123456
相关产品推荐
相关产品推荐

