Python Pandas DataFrame中基于规则匹配动态值更新列的实现方案
解决Pandas动态匹配DataFrame赋值的问题
我明白你的问题了——你当前的代码因为硬编码了source.loc['a1', 'Col4'],导致所有ColB='X'的行都被设置成固定值g1,而你需要的是根据每行的ColA值动态匹配source中对应的Col4值。这里有两种简单高效的实现方法:
方法1:使用map函数(最简洁)
map函数可以直接将target中指定行的ColA值映射到source的Col4列,完美实现动态匹配:
import pandas as pd import numpy as np # 初始化数据 target_d = {'ColA': ['a1', 'a1', 'a2', 'a2', 'a3', 'a3', 'a4'], 'ColB': ['X', 'Y', 'X', 'Y', 'X', 'Y', 'X'], 'ColC': ['c1', 'c2', 'c3', 'c4', 'c5', 'c6', 'c7'] } target = pd.DataFrame(data=target_d) source_d = {'Col1': ['a1', 'a2', 'a3', 'a4'], 'Col2': ['e1', 'e2', 'e3', 'e4'], 'Col3': ['f1', 'f2', 'f3', 'f4'], 'Col4': ['g1', 'g2', 'g3', 'g4'], } source = pd.DataFrame(data=source_d) source = source.set_index('Col1') # 核心修改:用map动态匹配 mask = target['ColB'] == 'X' target.loc[mask, 'ColC'] = target.loc[mask, 'ColA'].map(source['Col4'])
方法2:利用索引直接取值
因为source已经将Col1设为索引,我们可以直接通过ColA的值索引source,注意需要用.values来对齐赋值的维度:
# 核心修改:通过索引动态取值 mask = target['ColB'] == 'X' target.loc[mask, 'ColC'] = source.loc[target.loc[mask, 'ColA'], 'Col4'].values
运行结果
执行上述任意一种方法后,target的结果都会符合你的预期:
| ColA | ColB | ColC | |
|---|---|---|---|
| 0 | a1 | X | g1 |
| 1 | a1 | Y | c2 |
| 2 | a2 | X | g2 |
| 3 | a2 | Y | c4 |
| 4 | a3 | X | g3 |
| 5 | a3 | Y | c6 |
| 6 | a4 | X | g4 |
为什么原来的代码不行?
你原来的代码target.loc[target['ColB'] == 'X', 'ColC'] = source.loc['a1', 'Col4']中,source.loc['a1', 'Col4']返回的是单一标量值,Pandas会将这个值广播到所有符合条件的行,所以所有ColB='X'的行都被设置成了g1。而我们需要的是一个与筛选后行数匹配的序列,这样才能实现每行对应不同的值。
内容的提问来源于stack exchange,提问作者Matta
相关产品推荐
相关产品推荐

