Pandas含多IF条件的For循环问题:仅首个条件计算生效
问题分析与修复方案
嘿,我一眼就看出你的问题出在哪了——你用any()来判断列的条件,这玩意儿是检查整个列里有没有至少一个值满足条件,一旦有,就会给整个MWTP列都用第一个分支的计算结果,完全不管其他行的实际情况!这就是为啥只有首个条件的结果对,后面的条件根本没触发的原因。
为啥原来的代码不行?
举个例子,你的DWWC1980列里有第一行的16.71(<=18.25),所以any(df["DWWC1980"] <=18.25)会返回True,于是整个MWTP1980列都执行第一个if分支的计算,哪怕第三行的33.95明明符合第二个条件,也被强行用第一个分支的公式算了,结果自然不对。
修正后的代码(用Pandas向量化操作)
Pandas本来就是为批量处理列数据设计的,不用搞for循环里的标量判断,直接用np.where做逐行的多条件赋值就好,既高效又准确:
import numpy as np import pandas as pd # 读取数据(不用套一层pd.DataFrame,read_csv直接返回DataFrame) df = pd.read_csv("data.csv") print(df) # 遍历年份生成MWTP列 for year in range(1980, 2015, 5): dwwc_col = f"DWWC{year}" mwtp_col = f"MWTP{year}" # 定义三个条件对应的计算逻辑 # 条件1:DWWC <=18.25 cond1 = df[dwwc_col] <= 18.25 calc1 = ((10 - 33)/5) * (df[dwwc_col] - 5) + 10 # 条件2:18.25 < DWWC <=36.5 cond2 = (df[dwwc_col] > 18.25) & (df[dwwc_col] <= 36.5) # 注意:列名尽量用df['列名']的形式,避免和Pandas内置方法重名 calc2 = (10 / (df['two'] - df['three'])) * (df[dwwc_col] - df['three']) + df['three'] # 条件3:DWWC >36.5 cond3 = df[dwwc_col] > 36.5 calc3 = ((df['Three_value'] - 6)/(df['three'] - 5)) * (df[dwwc_col] - 6) # 用嵌套np.where实现逐行匹配条件赋值 df[mwtp_col] = np.where(cond1, calc1, np.where(cond2, calc2, calc3)) # 保存结果,index=False避免把默认索引存进去;如果要把ISO3当索引,读的时候加index_col='ISO3' df.to_csv('MWTP1.csv', index=False)
几个关键修改点
- 删掉
any():直接用列级布尔数组,这样每行都会被单独判断是否满足条件。 - 用
np.where替代if-elif-else:if-elif-else是标量判断,不适合处理Pandas的列数据,np.where能完美实现多条件的逐行赋值。 - 规范列名引用:把
df.two改成df['two'],防止列名和Pandas内置方法重名导致报错。 - 简化数据读取:
pd.read_csv直接返回DataFrame,不用再套一层pd.DataFrame()。
这样修改后,每行数据都会匹配自己对应的条件分支计算,结果就会和手动计算一致啦~
内容的提问来源于stack exchange,提问作者water77
相关产品推荐
相关产品推荐

