Pandas:基于其他列条件修改列值遇NaN问题求解
问题与解决方案
原始数据与需求
给定如下DataFrame:
import pandas as pd import random df = pd.DataFrame({ "Alpha": ["A", "A", "A", "A", "B", "B", "B", "B"], "Beta": ["C", "D", "E", "F", "C", "D", "E", "F"], "Value": [1, 2, 3, 4, 7, 2, 5, 1], })
需求:针对所有Alpha等于"A"的行,将其中Beta等于"D"的行的"Value"列值设置为Beta等于"F"的行的"Value"值乘以0.5,再乘以一个0.95至1.05之间的随机数。
用户尝试的代码
mask = (df['Alpha'] == 'A') df.loc[mask & (df['Beta'] == 'D'), 'Value'] = df.loc[mask & (df['Beta'] == 'F'), 'Value'] * 0.5 * random.uniform(0.95, 1.05)
执行后,目标行的Value变为NaN,即使移除0.5也无法解决。
问题原因
核心问题是索引不匹配:
df.loc[mask & (df['Beta'] == 'F')]返回的Series索引为3(对应原DataFrame第4行)df.loc[mask & (df['Beta'] == 'D')]返回的Series索引为1(对应原DataFrame第2行)
Pandas赋值时会按索引对齐,右侧Series中没有索引1的对应值,因此赋值结果为NaN。
解决方法
单分组场景(当前示例)
因为Alpha="A"分组下,Beta="F"和Beta="D"各仅一行,直接提取Beta="F"行的Value标量值再计算即可:
mask = (df['Alpha'] == 'A') # 提取Alpha=A且Beta=F的Value标量值 f_value = df.loc[mask & (df['Beta'] == 'F'), 'Value'].iloc[0] # 计算目标值 target_value = f_value * 0.5 * random.uniform(0.95, 1.05) # 赋值给目标行 df.loc[mask & (df['Beta'] == 'D'), 'Value'] = target_value
多分组扩展场景
如果后续每个Alpha分组下都有对应的D和F行,可通过groupby实现组内对应赋值:
def adjust_d_value(group): # 提取本组内Beta=F的Value值 f_val = group[group['Beta'] == 'F']['Value'].iloc[0] rand_factor = random.uniform(0.95, 1.05) # 给本组内Beta=D的行赋值 group.loc[group['Beta'] == 'D', 'Value'] = f_val * 0.5 * rand_factor return group df = df.groupby('Alpha').apply(adjust_d_value)
内容的提问来源于stack exchange,提问作者user6346482
相关产品推荐
相关产品推荐

