Pandas DataFrame中for循环与if语句的使用异常问题排查
Pandas新增Change列全显示"unch"的问题解决方法
嘿,我知道你为啥遇到这个问题了!咱们来一步步拆解:
问题根源
你写的for循环犯了一个典型的Pandas错误:每次循环都给整个Change列赋值,而不是对应行。而且因为你用了shift(-1),changeAbsolute列的最后一行会是NaN(因为最后一行没有下一行数据可以比对)。当循环遍历到这个NaN值时,NaN < 0和NaN > 0的判断结果都是False,所以会执行df["Change"] = "unch"——这直接把之前所有行的赋值结果全部覆盖,最终整个列都变成了"unch"。
另外多说一句,你之前生成changeAbsolute列的代码里,那个for循环完全是多余的,Pandas支持向量化操作,直接一行赋值就够了:
df["changeAbsolute"] = df["4. close"] - df["4. close"].shift(-1)
正确解决方案
Pandas处理这类逐行判断的场景,优先用向量化操作,不仅效率高,还能避免循环带来的赋值覆盖问题。这里给你推荐几种常用方法:
方法1:用numpy.where嵌套判断(最推荐,效率最高)
适合简单的多条件判断,一步到位:
import numpy as np # 先判断正负,最后处理0和NaN的情况 df["Change"] = np.where(df["changeAbsolute"] > 0, "+", np.where(df["changeAbsolute"] < 0, "-", "unch"))
方法2:用apply自定义函数(适合复杂逻辑)
如果之后需要扩展判断规则,可以写个自定义函数,用apply逐行处理:
import pandas as pd def get_change_symbol(val): if pd.isna(val): return "unch" # 单独处理NaN的情况 elif val > 0: return "+" elif val < 0: return "-" else: return "unch" df["Change"] = df["changeAbsolute"].apply(get_change_symbol)
方法3:用pd.cut区间划分
适合基于数值区间的分类场景:
import pandas as pd import numpy as np # 划分区间,对应正负标签 df["Change"] = pd.cut(df["changeAbsolute"], bins=[-np.inf, 0, np.inf], labels=["-", "+"], include_lowest=True) # 把NaN填充为"unch" df["Change"] = df["Change"].fillna("unch")
执行后的预期结果
不管用哪种方法,执行后df.head(3)都会得到你想要的结果:
1. open 2. high 3. low 4. close 5. volume changeAbsolute Change date 2021-02-18 241.80 243.93 240.86 243.79 16925563.0 -0.41 - 2021-02-17 241.32 244.31 240.94 244.20 21451617.0 0.50 + 2021-02-16 245.03 246.13 242.92 243.70 26728487.0 -1.29 -
内容的提问来源于stack exchange,提问作者Hank Gordon
相关产品推荐
相关产品推荐

