如何基于列值复制Pandas DataFrame记录并调整概率至总和为1
如何用Pandas复制DataFrame行并调整概率使每行与复制行概率和为1?
问题描述
现有如下Pandas DataFrame:
import pandas as pd ds = {'col1' : ["A","B"], 'probability' : [0.3, 0.6]} df = pd.DataFrame(data=ds)
输出结果:
col1 probability 0 A 0.3 1 B 0.6
需求:复制每一行,原行保留原始概率值,复制行的概率值设为1 - 原概率,最终得到如下结构的DataFrame:
col1 probability 0 A 0.3 1 A 0.7 2 B 0.6 3 B 0.4
解决方案
方法1:通过concat拼接逐行生成的子DataFrame
对每行单独生成原行和复制行的临时DataFrame,再拼接所有结果:
import pandas as pd ds = {'col1' : ["A","B"], 'probability' : [0.3, 0.6]} df = pd.DataFrame(data=ds) new_dfs = [] for _, row in df.iterrows(): # 添加原行 new_dfs.append(row.to_frame().T) # 复制行并修改概率 copied_row = row.copy() copied_row['probability'] = 1 - copied_row['probability'] new_dfs.append(copied_row.to_frame().T) # 拼接并重置索引 result = pd.concat(new_dfs, ignore_index=True) print(result)
方法2:利用explode展开概率列表
先为每行生成包含原概率和目标概率的列表,再通过explode展开成多行:
import pandas as pd ds = {'col1' : ["A","B"], 'probability' : [0.3, 0.6]} df = pd.DataFrame(data=ds) # 为每行生成概率列表 df['probability'] = df['probability'].apply(lambda x: [x, 1 - x]) # 展开列表并重置索引 result = df.explode('probability', ignore_index=True) # 转换为数值类型(可选,避免explode后出现字符串类型) result['probability'] = result['probability'].astype(float) print(result)
方法3:重复行后批量修改概率
先将原DataFrame的每行重复两次,再通过索引判断批量修改复制行的概率:
import pandas as pd ds = {'col1' : ["A","B"], 'probability' : [0.3, 0.6]} df = pd.DataFrame(data=ds) # 重复每行两次 result = df.loc[df.index.repeat(2)].reset_index(drop=True) # 对奇数索引的复制行修改概率 result.loc[result.index % 2 == 1, 'probability'] = 1 - result.loc[result.index % 2 == 0, 'probability'].values print(result)
内容的提问来源于stack exchange,提问作者Giampaolo Levorato
相关产品推荐
相关产品推荐

