Pandas比较R2ESL与MCL列取较小值追加到新列的实现咨询
实现逐行比较取最小值的两种方法
方法一:使用Pandas内置函数(更简洁,推荐)
Pandas提供了原生的逐行运算能力,不需要手动写for循环就能实现需求,代码如下:
import pandas as pd import numpy as np # 1. 读取Excel文件 excel_df = pd.read_excel('ESLs_MCL_Comparison_copy.xls') # 2. 将目标列转为float类型,避免字符串比较出错 excel_df['R2ESL'] = pd.to_numeric(excel_df['R2ESL'], errors='coerce') excel_df['MCL'] = pd.to_numeric(excel_df['MCL'], errors='coerce') # 3. 生成Limiting Criteria列 conditions = [ excel_df['R2ESL'] > excel_df['MCL'], excel_df['R2ESL'] < excel_df['MCL'], excel_df['R2ESL'] == excel_df['MCL'] ] choices = ['R2ESL', 'MCL', 'Equal'] excel_df['Limiting Criteria'] = np.select(conditions, choices, default='null') # 4. 直接取两列的最小值生成Lesser Value列,自动处理空值 excel_df['Lesser Value'] = excel_df[['R2ESL', 'MCL']].min(axis=1) # 输出结果 print(excel_df)
代码解释:
pd.to_numeric的errors='coerce'参数会把无法转成数字的异常值自动转为空值,避免代码报错np.select是多条件赋值的专用方法,比嵌套if更清晰min(axis=1)表示按行取最小值,axis=0是按列取,这里我们要逐行比较两列所以用axis=1
方法二:修改你现有的for循环代码
你原来的代码有两个小问题需要调整:
- 没有从读取的DataFrame里取出R2ESL、MCL两列的数据,直接遍历未定义的
R2ESL、MCL变量会报错 - 循环里的临时变量和你提前定义的列表重名了,会覆盖原列表导致逻辑出错
修改后的完整代码如下:
import pandas as pd excel_df = pd.read_excel('ESLs_MCL_Comparison_copy.xls') # 从DataFrame中取出两列转成float列表 R2ESL_float = [float(item) for item in excel_df['R2ESL']] MCL_float = [float(item) for item in excel_df['MCL']] result = [] result2 = [] # 临时变量改名,避免和外面的列表重名覆盖 for r_val, m_val in zip(R2ESL_float, MCL_float): if r_val > m_val: result.append("R2ESL") result2.append(m_val) # MCL更小,存入MCL的值 elif r_val < m_val: result.append("MCL") result2.append(r_val) # R2ESL更小,存入R2ESL的值 elif r_val == m_val: result.append("Equal") result2.append(r_val) # 两值相等,随便存哪个都可以 else: result.append("null") result2.append(None) # 异常情况存空值 excel_df["Limiting Criteria"] = result excel_df["Lesser Value"] = result2 print(excel_df)
运行结果示例:
| param | R2ESL | MCL | Limiting Criteria | Lesser Value |
|---|---|---|---|---|
| A | 10 | 7 | MCL | 7 |
| B | 100 | 150 | R2ESL | 100 |
| C | 55 | 55 | Equal | 55 |
内容的提问来源于stack exchange,提问作者WeijieD
相关产品推荐
相关产品推荐

