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

含不同缺失行的DataFrame中不确定度传递及零值排除方法问询

解决方案:多DataFrame零值过滤与不确定度传递合并

核心思路

针对不同区域的DataFrame,我们需要先过滤零值(缺失数据),利用uncertainties库自动处理不确定度传递,再按x分组加权平均,最终合并所有区域数据得到单条曲线。

步骤实现

1. 导入依赖库

import pandas as pd
import numpy as np
from uncertainties import unumpy as unp

2. 单DataFrame处理函数

该函数负责过滤零值、计算单区域内的加权平均及净信号:

def process_single_df(df):
    # 分离样本(s)、背景(b)及其误差列
    s_cols = [col for col in df.columns if col.startswith('s') and '_err' not in col]
    s_err_cols = [col for col in df.columns if col.startswith('s_err')]
    b_cols = [col for col in df.columns if col.startswith('b') and '_err' not in col]
    b_err_cols = [col for col in df.columns if col.startswith('b_err')]

    # 收集所有非零样本数据
    s_valid = []
    for s_col, err_col in zip(s_cols, s_err_cols):
        mask = df[s_col] != 0
        filtered = df.loc[mask, ['x', s_col, err_col]]
        filtered.columns = ['x', 'value', 'err']
        s_valid.append(filtered)
    s_all = pd.concat(s_valid, ignore_index=True)

    # 收集所有非零背景数据
    b_valid = []
    for b_col, err_col in zip(b_cols, b_err_cols):
        mask = df[b_col] != 0
        filtered = df.loc[mask, ['x', b_col, err_col]]
        filtered.columns = ['x', 'value', 'err']
        b_valid.append(filtered)
    b_all = pd.concat(b_valid, ignore_index=True)

    # 定义加权平均计算逻辑(权重为误差方差的倒数)
    def weighted_avg(group):
        y_with_err = unp.uarray(group['value'], group['err'])
        weights = 1 / (group['err'] ** 2)
        avg = np.sum(y_with_err * weights) / np.sum(weights)
        return pd.Series({
            'avg_val': unp.nominal_values(avg),
            'avg_err': unp.std_devs(avg)
        })

    # 按x分组计算样本、背景的加权平均
    s_avg = s_all.groupby('x').apply(weighted_avg).reset_index()
    s_avg.rename(columns={'avg_val': 's_avg', 'avg_err': 's_avg_err'}, inplace=True)
    b_avg = b_all.groupby('x').apply(weighted_avg).reset_index()
    b_avg.rename(columns={'avg_val': 'b_avg', 'avg_err': 'b_avg_err'}, inplace=True)

    # 合并并计算净信号(样本-背景)及不确定度
    merged = pd.merge(s_avg, b_avg, on='x', how='outer').fillna(0)
    net_signal = unp.uarray(merged['s_avg'], merged['s_avg_err']) - unp.uarray(merged['b_avg'], merged['b_avg_err'])
    merged['net_y'] = unp.nominal_values(net_signal)
    merged['net_y_err'] = unp.std_devs(net_signal)

    return merged

3. 多DataFrame合并函数

将所有区域处理后的结果按x再次加权平均,得到最终单条曲线:

def combine_all_dfs(df_list):
    combined = pd.concat(df_list, ignore_index=True)
    
    def combine_group(group):
        net_with_err = unp.uarray(group['net_y'], group['net_y_err'])
        weights = 1 / (group['net_y_err'] ** 2)
        final_avg = np.sum(net_with_err * weights) / np.sum(weights)
        return pd.Series({
            'final_net_y': unp.nominal_values(final_avg),
            'final_net_y_err': unp.std_devs(final_avg)
        })
    
    final_curve = combined.groupby('x').apply(combine_group).reset_index()
    return final_curve

4. 示例运行

# 构造示例数据(补充误差列)
cols = ['x', 's', 'b', 's_err', 'b_err']
A = pd.DataFrame(np.array([[1, 2, 3, 0.1, 0.2], [4, 5, 0, 0.1, 0.2], [6, 7, 0, 0.1, 0.2], [1, 1, 0, 0.1, 0.2], [2, 2, 0, 0.1, 0.2]]), columns=cols)
B = pd.DataFrame(np.array([[1, 2, 3, 0.1, 0.2], [4, 0, 5, 0.1, 0.2], [6, 0, 7, 0.1, 0.2], [1, 0, 1, 0.1, 0.2], [2, 0, 2, 0.1, 0.2]]), columns=cols)

# 处理单个DataFrame
processed_A = process_single_df(A)
processed_B = process_single_df(B)

# 合并得到最终曲线
final_curve = combine_all_dfs([processed_A, processed_B])
print(final_curve)

关键说明

  • 零值过滤:通过布尔索引(df[col] != 0)实现,本质是利用numpy掩码功能提取有效数据,确保缺失值不参与计算。
  • 不确定度传递:uncertainties.unumpy自动处理加减、加权平均的误差传递,无需手动推导公式。
  • 合并逻辑:先在单区域内合并多列数据,再跨区域合并同一x的结果,保证最终曲线的一致性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 23:35:55