Pandas按月份重采样数据框:浮点列求和、字符串列取唯一值
问题原因
原代码的核心问题是对单列重采样后直接赋值回原DataFrame,原DataFrame的索引仍是单日粒度,重采样结果仅能匹配到月末日期的索引,因此只会在月末行插入统计值,不会自动删除单日行,也不会生成仅月度粒度的结果。
解决方案
直接使用resample() + agg()方法一次性对不同类型的列指定不同的聚合规则,无需循环单列处理,直接生成月度粒度的新DataFrame。
完整代码如下:
import pandas as pd # 首先确保你的df索引是datetime类型(如果还没转换可以先执行) df.index = pd.to_datetime(df.index) # 定义不同类型列的聚合规则 agg_rules = {} for col in df.columns: if "float" in col: # 浮点列按月求和,默认自动忽略NaN agg_rules[col] = "sum" elif "string" in col: # 字符串列先剔除NaN,再取唯一值,拼接为逗号分隔的字符串 agg_rules[col] = lambda x: ", ".join(x.dropna().unique()) # 按月重采样,按规则聚合生成月度结果 df_monthly = df.resample("M").agg(agg_rules) # 批量给列名加MONTHLY后缀 df_monthly.columns = [f"{col} MONTHLY" for col in df_monthly.columns] # 可选:将索引格式调整为你期望的%m/%Y格式 df_monthly.index = df_monthly.index.strftime("%m/%Y")
效果验证
用你提供的示例输入运行后,输出结果和预期完全一致:
float_1 MONTHLY float_2 MONTHLY string_1 MONTHLY string_2 MONTHLY 12/2019 2 5 a a, b 01/2020 5 9 a, b c, d
补充说明
- 如果你的列名没有float/string标识,也可以根据列的实际dtype判断聚合规则,把判断条件改为
pd.api.types.is_float_dtype(df[col])和pd.api.types.is_string_dtype(df[col])即可适配。 - 字符串列的聚合逻辑中加入了
dropna(),会自动过滤当月的空值再取唯一值拼接,适配存在随机NaN的场景。
内容的提问来源于stack exchange,提问作者Chris Macaluso
相关产品推荐
相关产品推荐

