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

Python中DataFrame分位数过滤子集后合并失败问题求助

问题解决:按分组和时间子集剔除极值后合并DataFrame

问题描述

现有三列数据:ETA(eta/km*100)(数值型)、Climate和month。需求是:

  • 按每个Climate分组
  • 对每个分组,取month < 4、month <7、month <10、month <13这四个时间子集
  • 每个子集剔除ETA(eta/km*100)列中低于0.05分位数和高于0.95分位数的极值
  • 将所有处理后的子集合并为一个最终DataFrame

当前遇到的问题:循环内子集处理正常,但最终合并时仅保留最后一个子集(Hurricane、最后3个月),且极值未被剔除;尝试concat、add、append、+=均失败,+=会导致所有值变为NaN。

错误原因分析

  1. 初始化错误:newDf = df_Cl; newDf.iloc[0:0]这种方式并没有创建真正的空DataFrame,后续操作会受原df_Cl结构影响。
  2. 合并方法错误:
    • newDf.add(df_Temp)是元素级别的加法运算,不是数据合并,且未将结果赋值回newDf,等于没执行任何有效合并操作。
    • newDf += df_Temp同样是元素加法,当两个DataFrame索引不匹配时,对应位置会生成NaN,完全不符合数据行合并的需求。
  3. 未保留中间结果:循环中处理后的df_Temp没有被正确收集或追加到最终DataFrame中,导致之前的处理结果全部丢失。

正确解决方案

方案1:用列表收集所有处理后的子集,最后一次性合并(推荐,效率更高)

import pandas as pd

# 初始化空列表用于存储处理后的子集
processed_dfs = []
Climate = ['Sunny', 'Cloudy', 'Foggy', 'Rain', 'Storm', 'Hurricane']

for cl in Climate:
    print(cl)
    for num in range(4, 14, 3):
        print(num)
        # 筛选当前Climate和时间子集
        df_Temp = df.loc[(df['Climate'] == cl) & (df['month'] < num)]
        # 计算分位数
        bajo = df_Temp['eta/km*100'].quantile(0.05)
        alto = df_Temp['eta/km*100'].quantile(0.95)
        # 剔除极值,用&连接条件更高效
        df_Temp = df_Temp[(df_Temp['eta/km*100'] > bajo) & (df_Temp['eta/km*100'] < alto)]
        # 将处理后的子集加入列表
        processed_dfs.append(df_Temp)

# 合并所有子集为最终DataFrame,ignore_index=True重置索引避免冲突
newDf = pd.concat(processed_dfs, ignore_index=True)

方案2:循环内逐步合并(适合数据量较小的场景)

import pandas as pd

# 初始化空DataFrame,保持和原数据一致的列结构
newDf = pd.DataFrame(columns=df.columns, dtype=df.dtypes)
Climate = ['Sunny', 'Cloudy', 'Foggy', 'Rain', 'Storm', 'Hurricane']

for cl in Climate:
    print(cl)
    for num in range(4, 14, 3):
        print(num)
        df_Temp = df.loc[(df['Climate'] == cl) & (df['month'] < num)]
        bajo = df_Temp['eta/km*100'].quantile(0.05)
        alto = df_Temp['eta/km*100'].quantile(0.95)
        df_Temp = df_Temp[(df_Temp['eta/km*100'] > bajo) & (df_Temp['eta/km*100'] < alto)]
        # 逐步合并,ignore_index=True避免索引重复
        newDf = pd.concat([newDf, df_Temp], ignore_index=True)

关键注意点

  • 剔除极值时,用&连接两个条件,比两次单独索引筛选更高效。
  • 合并数据行必须使用pd.concat,而不是算术运算方法(add/+=),后者仅用于数值计算,不适合行合并。
  • 使用ignore_index=True可以避免不同子集的索引重复或冲突,生成连续的新索引。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 09:37:50