MELD与MELD-Na评分Python实现准确性核查请求
MELD/MELD-Na公式Python实现错误核查与修正
问题背景
作为研究者,我正在用Python实现肝硬化评分的MELD和MELD-Na公式,代码可运行但部分结果与手动计算值不符,需要核查代码实现是否正确。
官方公式
MELD = 1.33(女性额外加) + [4.56 × loge(bilirubin)] + [0.82 × (137 – sodium)] – [0.24 × (137 – sodium) × loge(bilirubin)] + [9.09 × loge(INR)] + [11.14 × loge(creatinine)] + [1.85 × (3.5 – albumin)] – [1.83 × (3.5 – albumin) × loge(creatinine)] + 6
MELD-Na = MELD + 1.32 × (137-Na) – [0.033 × MELD × (137-Na)]
原实现代码
import pandas as pd import math def calculate_meld(bilirubin, sodium, INR, creatinine, albumin, Sex): if bilirubin <= 0 or sodium <= 0 or INR <= 0 or creatinine <= 0: return None # Return None if any of the required parameters are non-positive if Sex.lower() == 'female': meld_score = (1.33 + 4.56 * math.log(bilirubin) + 0.82 * (137 - sodium) - 0.24 * (137 - sodium) * math.log(bilirubin) + 9.09 * math.log(INR) + 11.14 * math.log(creatinine) + 1.85 * (3.5 - albumin) - 1.83 * (3.5 - albumin) - 1.83 * (3.5 - albumin) * math.log(creatinine) + 6) else: meld_score = (4.56 * math.log(bilirubin) + 0.82 * (137 - sodium) - 0.24 * (137 - sodium) * math.log(bilirubin) + 9.09 * math.log(INR) + 11.14 * math.log(creatinine) + 1.85 * (3.5 - albumin) - 1.83 * (3.5 - albumin) - 1.83 * (3.5 - albumin) * math.log(creatinine) + 6) meld_score = round(meld_score) meld_score = max(6, min(meld_score, 40)) # Limiting the MELD score between 6 and 40 return meld_score def calculate_meld_na(meld, sodium): if meld is None: return None # Return None if MELD score is None meld_na_score = meld + 1.32 * (137 - sodium) - 0.033 * meld * (137 - sodium) meld_na_score = round(meld_na_score) meld_na_score = max(6, min(meld_na_score, 40)) # Limiting the MELD-Na score between 6 and 40 return meld_na_score # Load data from Excel file data = pd.read_excel('ICC NSQIP Data.xlsx') # Drop rows with missing data data.dropna(subset=['Total Bilirubin', 'Serum Sodium', 'INR', 'Serum Creatinine', 'Albumin', 'Sex'], inplace=True) # Extract relevant columns bilirubin = data['Total Bilirubin'] sodium = data['Serum Sodium'] INR = data['INR'] creatinine = data['Serum Creatinine'] albumin = data['Albumin'] Sex = data['Sex'] # Calculate MELD and MELD-Na scores meld_scores = [calculate_meld(b, s, i, c, a, g) for b, s, i, c, a, g in zip(bilirubin, sodium, INR, creatinine, albumin, Sex)] meld_scores = [score if score is not None else 0 for score in meld_scores] # Replace None with 0 meld_na_scores = [calculate_meld_na(m, s) for m, s in zip(meld_scores, sodium)] # Add MELD and MELD-Na scores to the DataFrame data['MELD Score'] = meld_scores data['MELD-Na Score'] = meld_na_scores # Save the updated DataFrame to a new Excel file data.to_excel('liver_data_updated_2.xlsx', index=False)
错误分析与修正
核心错误:公式项重复计算
原代码中calculate_meld函数的男女分支里,都多写了一行- 1.83 * (3.5 - albumin),这在官方MELD公式中不存在。官方公式仅包含– [1.83 × (3.5 – albumin) × loge(creatinine)]这一项,多余的减项会导致计算结果偏低,与手动值不符。
修正后的calculate_meld函数
def calculate_meld(bilirubin, sodium, INR, creatinine, albumin, Sex): if bilirubin <= 0 or sodium <= 0 or INR <= 0 or creatinine <= 0: return None # Return None if any of the required parameters are non-positive base_score = (4.56 * math.log(bilirubin) + 0.82 * (137 - sodium) - 0.24 * (137 - sodium) * math.log(bilirubin) + 9.09 * math.log(INR) + 11.14 * math.log(creatinine) + 1.85 * (3.5 - albumin) - 1.83 * (3.5 - albumin) * math.log(creatinine) + 6) if Sex.lower() == 'female': meld_score = base_score + 1.33 else: meld_score = base_score meld_score = round(meld_score) meld_score = max(6, min(meld_score, 40)) # Limiting the MELD score between 6 and 40 return meld_score
其他验证点
- Python的
math.log()默认是自然对数(loge),符合公式要求,无需修改。 - MELD-Na的公式实现正确,无逻辑错误。
- 数值截断(限制在6-40之间)符合临床评分规范。
额外优化建议
将None替换为0可能不符合临床逻辑,建议保留None或用NaN填充,避免后续统计误差:
meld_scores = [score if score is not None else pd.NA for score in meld_scores]
内容的提问来源于stack exchange,提问作者Not a Wrench
相关产品推荐
相关产品推荐

