如何在Python循环中向DataFrame追加函数返回的变量?
问题
目标生成如下格式的输出表格:
campaign | mean | left | right A | 5% | 0% | 10% B | 8% | 2% | 6% etc.
使用Python循环调用bootstrap_ci函数获取campaign、mean、left、right四个变量,但追加新DataFrame时失败,最终返回空DataFrame。相关代码如下:
bootstrap_ci函数代码
import numpy as np def bootstrap_ci(df, variable, classes, repetitions = 1000, alpha = 0.05, random_state=None): df = df[[variable, classes]] bootstrap_sample_size = len(df) mean_diffs = [] for i in range(repetitions): bootstrap_sample = df.sample(n = bootstrap_sample_size, replace = True, random_state = random_state) mean_diff = bootstrap_sample.groupby(classes).mean().iloc[1,0] - bootstrap_sample.groupby(classes).mean().iloc[0,0] mean_diffs.append(mean_diff) left = np.percentile(mean_diffs, alpha/2*100)*(-1) right = np.percentile(mean_diffs, 100-alpha/2*100)*(-1) mean = -(df.groupby(classes).mean().iloc[1,0] - df.groupby(classes).mean().iloc[0,0])
循环调用及追加代码
df = pd.DataFrame([]) # 初始化新df for i in campaigns: print(f'Lift for: {i}') bootstrap_ci(df[df['campaign_name']==i],'conversion','group') df = df.append(i, mean, left, right) # 将相关变量追加到df
解决建议
1. 修复bootstrap_ci函数的返回值与计算逻辑
- 原函数无返回值,调用后无法获取
mean、left、right变量 - 原函数中
left、right的计算缩进错误,应放在循环结束后(否则每次循环都会重复计算百分位数,效率低且结果不准确)
修改后的函数:
import numpy as np import pandas as pd def bootstrap_ci(df, variable, classes, repetitions=1000, alpha=0.05, random_state=None): df = df[[variable, classes]] bootstrap_sample_size = len(df) mean_diffs = [] for _ in range(repetitions): bootstrap_sample = df.sample(n=bootstrap_sample_size, replace=True, random_state=random_state) group_means = bootstrap_sample.groupby(classes).mean().iloc[:, 0] mean_diff = group_means.iloc[1] - group_means.iloc[0] mean_diffs.append(mean_diff) # 循环结束后统一计算置信区间与均值 left = np.percentile(mean_diffs, alpha/2 * 100) * (-1) right = np.percentile(mean_diffs, 100 - alpha/2 * 100) * (-1) original_group_means = df.groupby(classes).mean().iloc[:, 0] mean = -(original_group_means.iloc[1] - original_group_means.iloc[0]) # 返回计算结果 return mean, left, right
2. 修复DataFrame的追加逻辑
df.append()已被Pandas弃用,推荐先收集所有结果为字典列表,最后一次性转为DataFrame,效率更高且不易出错- 原代码未接收
bootstrap_ci的返回值,导致mean、left、right未定义
修改后的循环代码:
# 初始化列表存储所有campaign的结果 results = [] for campaign in campaigns: print(f'Lift for: {campaign}') # 接收函数返回的三个计算值 mean, left, right = bootstrap_ci(df[df['campaign_name'] == campaign], 'conversion', 'group') # 将当前campaign的结果存入字典,追加到列表 results.append({ 'campaign': campaign, 'mean': f'{mean*100:.1f}%', # 转为百分比格式 'left': f'{left*100:.1f}%', 'right': f'{right*100:.1f}%' }) # 将列表转为目标格式的DataFrame result_df = pd.DataFrame(results) print(result_df)
3. 额外优化点
- 给
random_state传入固定值(如42),保证结果可复现 - 如果
group列的分组顺序不确定,建议用分组名索引替代iloc,避免索引错误,例如假设分组为control和treatment:
group_means = bootstrap_sample.groupby(classes).mean().loc[:, variable] mean_diff = group_means['treatment'] - group_means['control']
内容的提问来源于stack exchange,提问作者Lakem
相关产品推荐
相关产品推荐

